0

I'm currently using jQuery's $.getScript within my content script to import more Javascript files into my content script. This works very well for me to get all my Javascript files imported, but I am running into an issue where I can't use chrome.runtime.sendMessage inside the imported javascript files to communicate with my background scripts, presumably because the function isn't recognized within a script that's been processed by $.getScript (please do correct me if I'm wrong).

In content.js (injected directly via the manifest file), I have the following code:

$.getScript(chrome.extension.getURL('js/angular-1.2.26-min.js'), function(data) {
  $.getScript(chrome.extension.getURL('app/app.js'), function(data) {
    $.getScript(chrome.extension.getURL('app/overview/overview-controller.js'), function(data) {
      $.getScript(chrome.extension.getURL('js/angular-bootstrap.js'), function(data) {
      })
    })
  })
})

And inside app/app.js (or any of the injected files), I try putting a sendMessage call anywhere, but nothing gets sent. (I log the onMessage event listener in the background)

chrome.runtime.sendMessage({msg: 'test'}, function(response) { alert('done') })

Note: I have also tried importing the Javascript files by sending a message to the background script to use chrome.tabs.executeScrip instead, but I need to be able to inject the javascript files only at a specific time and in a specific frame, so that doesn't help. I've also tried using the 3rd party executeScriptInFrame library but that doesn't seem to be working either. I run into "Blocked script execution in '{{URL}}' because the document's frame is sandboxed and the 'allow-scripts' permission is not set"

My questions:

  • Is there an effective solution to using chrome.runtime.sendMessage inside a script that's been injected using $.getScript?

  • Is there a way to use executeScript inside a content script?

  • Is there an effective way to inject content scripts into a particular frame? Again, from above -- I tried a third party library but ran into an issue regarding the frame's sandboxing. But this is strange since I am able to successfully inject content scripts to that frame when using the manifest to do it directly.

Thanks!

Edward Sun
  • 1,541
  • 3
  • 15
  • 26

1 Answers1

0

Well, that's an interesting question.

Most methods rely <script> injection, which adds code to the wrong (page) context that has no access to Chrome APIs. I assume this is how $.getScript works. So, this will not work as intended.

Another method is using eval(). According to the documentation, eval() is allowed (but discouraged) in Content Scripts. So you can, in principle, load the script file in a XHR / jQuery AJAX request and then eval() its contents. This should work.

Lastly, you could modify your content scripts only to execute if some condition is met (say, a variable is set), and so injecting into all frames of a tab should be less of a problem. This could potentially be messy though. Note that a content script can find itself in the iframe hierarchy, which may be useful.

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206