tabs.executeScript - 传递参数和使用库?

IT技术 javascript jquery google-chrome google-chrome-extension
2021-03-18 17:55:12

我正在编写一个 Chrome 扩展,它需要根据一些给定的参数修改特定域中的页面,这需要 XSS 才能获得,所以简单地使用内容脚本似乎是不可能的。所以,我决定使用 tabs.executeScript 注入脚本。

现在我需要知道两件事:第一,在使用executeScript时如何将参数传递给脚本?我想我可以使用消息,但是在注入脚本时没有更直接的方法来传递参数吗?

其次,我的脚本使用 jQuery,所以我需要以某种方式包含 jQuery。这很愚蠢,但我不知道该怎么做。到目前为止,我在我正在编写的 HTML 页面中嵌入了 jQuery(例如 background.html)。

3个回答

如果您不想使用消息传递,则:

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应该放在扩展文件夹中)。脚本选项将scriptOptionsscript.js.

使用消息传递同样简单:

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
        });
    });
});

您需要将请求侦听器添加到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);
});
真的吗?嗯,我没有意识到这一点。谢谢!
2021-04-25 17:55:12
好吧,看,这就是我的想法 - 该选项卡的内容脚本隔离世界。问题是,如果清单中有两个内容脚本,它们最终会出现在两个不同的孤立世界中。但是在这里,您似乎有两个独立的executeScript调用,它们最终都在同一个孤立的世界中。
2021-05-04 17:55:12
@Kragen 不,所有内容脚本(当然来自同一个扩展)都在同一个世界中运行。无论您是在清单中还是通过executeScript.
2021-05-07 17:55:12
那么所有executeScript调用都将代码放入选项卡中的同一个孤立世界中吗?我认为他们不会:“孤立的世界允许每个内容脚本对其 JavaScript 环境进行更改,而不必担心与页面或其他内容脚本发生冲突”
2021-05-17 17:55:12
@KragenexecuteScript等于在清单中声明一个内容脚本。它不是在选项卡的孤立世界中执行,而是在内容脚本的孤立世界中执行。
2021-05-21 17:55:12

基于上述直接方法,我能够直接从 Chrome 扩展程序的后台脚本中将代码注入新选项卡。但是,请注意,executeScript 命令的代码部分不会简单地采用变量,而只会采用字符串。因此,经过实验,我发现我们需要预先设置命令字符串并包含我们想要的变量。像这样:

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});
      });
});

这工作得很好!

包含依赖项的更好方法

将依赖库(和其他 .js 文件)添加到您的后台脚本中manifest.json

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

在应用程序代码之前列出依赖项,以便在之前加载它们。

参考:注册后台脚本

注意:这将执行脚本的预先加载,而不是像executeScript.