36

I am writing a Chrome extension that needs to modify pages in a specific domain according to some given parameter, which needs XSS in order to be obtained, so simply using a content script seems impossible. So, I've decided to inject the script using tabs.executeScript.

Now I need to know two things: First, how can I pass parameters to the script when using executeScript? I guess I can use messages, but isn't there a more direct way to pass the parameter while injecting the script?

Second, my script uses jQuery, so I need to include jQuery somehow. It's silly, but I'm not sure how to do it. So far, I embedded jQuery in the HTML page I was writing (for example background.html).

Makyen
33.6k12 gold badges94 silver badges128 bronze badges
asked Feb 12, 2011 at 7:48
2

3 Answers 3

59

If you don't want to use messaging then:

chrome.tabs.executeScript(tabId, {file: "jquery.js"}, function(){
 chrome.tabs.executeScript(tabId, {code: "var scriptOptions = {param1:'value1',param2:'value2'};"}, function(){
 chrome.tabs.executeScript(tabId, {file: "script.js"}, function(){
 //all injected
 });
 });
});

(jquery.js should be placed into extension folder). Script options will be available inside scriptOptions variable in the script.js.

With messaging it is just as easy:

chrome.tabs.executeScript(tabId, {file: "jquery.js"}, function(){
 chrome.tabs.executeScript(tabId, {file: "script.js"}, function(){
 chrome.tabs.sendMessage(tabId, {scriptOptions: {param1:'value1',param2:'value2'}}, function(){
 //all injected
 });
 });
});

You would need to add a request listener to script.js:

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
 var scriptOptions = message.scriptOptions;
 console.log('param1', scriptOptions.param1);
 console.log('param2', scriptOptions.param2);
 doSomething(scriptOptions.param1, scriptOptions.param2);
});
woxxom
75.1k15 gold badges161 silver badges164 bronze badges
answered Feb 12, 2011 at 18:24
Sign up to request clarification or add additional context in comments.

6 Comments

So are all executeScript calls putting code into the same isolated world in the tab? I thought they wouldn't: "Isolated worlds allow each content script to make changes to its JavaScript environment without worrying about conflicting with the page or with other content scripts"
@Kragen executeScript is equal to declaring a content script in the manifest. It is not executed in isolated world of a tab, it is executed in isolated world of a content script.
Well, see, that's what I thought — a content-script isolated world for that tab. The thing is, if you have two content scripts in the manifest, they end up in two different isolated worlds. But here you seem to have two separate executeScript calls that end up in the same isolated world.
@Kragen No, all content scripts (from the same extension of course) are running in the same world. No matter whether you declare them in a manifest or through executeScript.
I ran into a similar issue, and wrote a Q&A with some code to abstract the approach mentioned above: Injecting multiple scripts through executeScript in Google Chrome
|
2

Building off the direct method above, I was able to inject code into a new tab directly from the background script on my Chrome Extension. However, be advised that the code section of the executeScript command will not simply take variables, but only a string. Therefore, after experimenting, I found we need to setup the string of commands beforehand and include the variables we want. Like this:

var sendCode = 'document.getElementsByClassName("form-control n-gram")[0].value = "' + TMObj.brand + '";';
var TMUrl = "http://website.com";
chrome.tabs.create({ url: TMUrl }, function(tab){
 chrome.tabs.executeScript(null, {code: sendCode});
 });
});

This worked well!

answered Dec 12, 2017 at 22:31

Comments

2

Better way to include dependencies

Add the dependant libraries (and other .js files) to the background scripts in your manifest.json by:

"background": {
 "scripts": [
 "jquery.js",
 "main.js"
]

List the dependencies before app code so that they are loaded before.

Reference: Register Background Scripts

Note: this would perform eager-loading of the scripts, instead of lazy-loading as with executeScript.

answered Dec 1, 2018 at 9:46

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.