问题 Chrome扩展程序:如何检测内容脚本是否已加载到选项卡中?


我的后台脚本中有以下代码:

chrome.tabs.onUpdated.addListener(function(tabId, changeinfo, tab) {
    if (changeinfo.status !== 'complete')
        return;

    if (!matchesUrlFilters(tab.url))
        return;

    chrome.tabs.executeScript(tabId, { file: "jquery-1.7.1.min.js" }, function() {
        chrome.tabs.executeScript(tabId, { file: "enhance.js" });
    });
});

但是,在某些情况下,这似乎会两次注入我的内容脚本(可能会在以下情况下发生) enhance.js 不 window.history.pushState)。

如何确定选项卡是否已包含我的内容脚本?我试过了 chrome.tabs.sendRequest 但如果尚未添加内容脚本,它从不调用回调。


12284
2018-01-14 02:14


起源

当脚本被注入两次时,请执行两次操作 enhance.js 脚本与共享变量共享一个执行环境? - abraham
我不知道(现在可能永远不会检查完全解决问题的答案)。 - Andrey Shchekin
我知道这是一个老问题,但我也遇到了这个问题。我没有为已加载的脚本添加检查,而只是从manifest.json的“content_scripts”部分删除脚本,因为我委托了脚本的执行并且不希望它总是被加载。 - Andrew


答案:


编辑:对此答案的第一条评论进行了更新。

你可能会尝试这样的事情。添加一个onRequest侦听器,该侦听器将用作回调以加载所需的脚本,但它们仅基于作为请求消息的一部分发送的值进行加载。然后使用executeScript直接调用“代码”,发送带有全局变量值(如果存在)的消息。

chrome.tabs.onUpdated.addListener(function(tabId, changeinfo, tab) {
    ...

    // execute a content script that immediately sends back a message 
    // that checks for the value of a global variable which is set when
    // the library has been loaded
    chrome.tabs.executeScript(tabId, {
        code: "chrome.extension.sendRequest({ loaded: EnhanceLibIsLoaded || false });"
    });

    ...
});

// listen for requests
chrome.extension.onRequest.addListener(function(req, sender, sendResponse) {
    if (req.loaded === false) {
        chrome.tabs.executeScript(tabId, { file: "jquery-1.7.1.min.js" }, function() {
            chrome.tabs.executeScript(tabId, { file: "enhance.js" }, function() {
                // set the global variable that the scripts have been loaded
                // this could also be set as part of the enhance.js lib
                chrome.tabs.executeScript(tabId, { code: "var EnhanceLibIsLoaded = true;" });
            });
        });
     }
});

10
2018-01-14 07:46



这是天才,我修改了一下(感动 onRequest.addListener 外面),但无论如何它完美无缺。注意它应该是 chrome.extension.onRequest.addListener 代替 chrome.tabs.onUpdated.addListener。 - Andrey Shchekin
很高兴听到它有效,我根据你的评论编辑了答案(让我知道如果我没有正确 - 或者随意编辑,所以它是)。 - Adam Ayres
我想用这个但是在consol中有一个错误说: Uncaught ReferenceError: EnhanceLibIsLoaded is not defined :( - Alireza
我和上面的@Youhan有同样的问题,即使是 isLoaded || false 检查...我将注入的代码修改为: "if(isLoaded){isLoaded=isLoaded}else{ var isLoaded=false;} chrome.runtime.sendMessage(...);" - anson
这对我有用,以回应未捕获的参考错误: chrome.tabs.executeScript(null, { code: "if (typeof(contentScriptIsLoaded) == 'undefined') contentScriptIsLoaded = false; chrome.runtime.sendMessage({ loaded: contentScriptIsLoaded });" }); - zoxxx