简体   繁体   中英

Why can't I use jQuery after it's dynamically injected from a chrome extension's content-script?

When run as a script in the usual way on a page, this code prints the version of jQuery after it is dynamically injected into a page. But in my chrome-extension, when I try to print jQuery's version after I dynamically inject it, the output is undefined .

// create iframe
var frame = document.createElement("iframe");

// when frame loads
frame.addEventListener("load", function() {
  // create script to dynamically inject into DOM
  var script = frame.contentWindow.document.createElement("script");
  // when script loads print jquery version
  script.addEventListener("load", function() {
    console.log(frame.contentWindow.$.fn.jquery); // output -> 2.2.1
  });
  frame.contentWindow.document.head.appendChild(script);
  script.src = "https://code.jquery.com/jquery-2.2.1.js";
});

document.body.appendChild(frame);

So this is my problem:

I have to dynamically inject some code (I'm using jQuery as an example) into an iframe because I need it to have the correct context of the iframe.contentWindow as the window.

The problem is that whenever I try to use the global that is created with the a script such as someModule.js using frame.contentWindow.someModule (in this case it's frame.contentWindow.$ since I injected the jQuery source code) it is undefined. I think this is something to do with it being a chrome extension (like the chrome extension javascript is isolated from the other code)

My question:

  1. Why does this happen?

  2. How can I bypass (or any solution to this) it?
    2.1. How can I dynamically add JavaScript (a file, or some code) so that it's in the context of an iFrame (and not the parent window). I must do it during run-time as it's a chrome extension with a content-script.

Or can I possibly run the chrome extension content-script directly in the iframe?

Fiddle with the code above: https://jsfiddle.net/wj83oytd/5/

Found the problem,

Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts.

https://developer.chrome.com/extensions/content_scripts#execution-environment

Solution,

Dynamically inject the code you want to run as inline JavaScript code as well, instead of running it in the content-script

Code that doesn't work:

 // calling it in the content-script
 console.log(frame.contentWindow.$.fn.jquery); // undefined

Solution:

var script = frame.contentWindow.document.createElement("script");
script.innerHTML = "console.log(window.$.fn.jquery);"; // set script code
// adding it to the frame and running it in it's context
frame.contentWindow.document.body.appendChild(rmptipScript); // injects the code
// prints 2.2.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM