简体   繁体   English

动态加载内容脚本(chrome扩展名)

[英]Dynamic loading of content script (chrome extension)

I have an chrome extension, with 2 content script injected by manifest and one background script. 我有一个chrome扩展,有一个由manifest和一个后台脚本注入的内容脚本。

{
    "manifest_version": 2,
    "name": "Test",
    "permissions": [
        "tabs", "<all_urls>", "activeTab", "storage" 
    ],

    "content_scripts": [
        {
            "matches": ["http://*/*", "https://*/*"],
            "js": [
                   "content/autofill/lib_generic.js",
                   "content/autofill/lib.js"],
            "run_at": "document_end"
        }
    ],

  "web_accessible_resources": [
        "content/specific_scripts/*"
    ],

    "background": {
        "scripts": ["background.js"],
        "persistent": false
    }

}

lib_generic.js contains one function named apply_forms(...) (its description is not important). lib_generic.js包含一个名为apply_forms(...)函数(其描述并不重要)。 The function is called from lib.js file. 该函数从lib.js文件中调用。 But this procedure doesn't work with several pages, so for each such page a I have a special script - also with only one function named apply_forms(...) . 但是这个过程不适用于几个页面,所以对于每个这样的页面,我有一个特殊的脚本 - 也只有一个名为apply_forms(...)函数。

I have a function, which takes current domain as input and returns name of desired specific script or false if generic should be used. 我有一个函数,它将当前域作为输入并返回所需特定脚本的名称,如果应该使用泛型,则返回false

There is too many files and it's logic is more complicated, so I can't just list all (url, script) pairs in "content_scripts" directive (I also don't want to inject all specific files as content script). 文件太多而且它的逻辑更复杂,所以我不能只在"content_scripts"指令中列出所有(url, script)对(我也不想将所有特定文件作为内容脚本注入)。

I've tried something like this in background (note that it's only for demonstration): 我在背景中尝试过类似的东西(请注意,它仅用于演示):

var url = ""; //url of current tab

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if(changeInfo.status == "complete") {
        var filename = getSpecificFilename(url);
        chrome.tabs.executeScript(tabId, {file: filename}, function() {
            //script injected
        });
    }
});

NOTE: getSpecificFilename(...) will always return a name 注意:getSpecificFilename(...)将始终返回一个名称

But I get Unchecked runtime.lastError while running tabs.executeScript: Cannot access a chrome:// URL on the 5th line. 但是Unchecked runtime.lastError while running tabs.executeScript: Cannot access a chrome:// URL我得到Unchecked runtime.lastError while running tabs.executeScript: Cannot access a chrome:// URL第5行Unchecked runtime.lastError while running tabs.executeScript: Cannot access a chrome:// URL

Can anyone help me with this? 谁能帮我这个? Is it the good way to "override` function definition dynamically, or should I go different way (which one, then). 它是动态“覆盖”函数定义的好方法,还是应该采用不同的方式(然后是哪一种)。

Thanks. 谢谢。

This means, probably, that you're getting an onUpdated event on an extension/internals page (popup? options page? detached dev tools?). 这可能意味着您在扩展/内部页面上获得了onUpdated事件(弹出窗口?选项页面?分离开发工具?)。

One option is to filter by URL: 一种选择是按URL过滤:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if(changeInfo.status == "complete") {
        if(!tab.url.match(/^http/)) { return; } // Wrong scheme
        var filename = getSpecificFilename(url);
        chrome.tabs.executeScript(tabId, {file: filename}, function() {
            //script injected
        });
    }
});

Another (and probably better) option is to make your content script request this injection: 另一个(可能更好)选项是让您的内容脚本请求此注入:

// content script
chrome.runtime.sendMessage({injectSpecific : true}, function(response) {
  // Script injected, we can proceed
  if(response.done) { apply_forms(/*...*/); }
  else { /* error handling */ }
});

// background script
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  if(message.injectSpecific){
    var filename = getSpecificFilename(sender.url);
    chrome.tabs.executeScript(sender.tab.id, {file: filename}, function() {
      sendResponse({ done: true });
    });
    return true; // Required for async sendResponse()
  }
});

This way you know that a content script is injected and initiated this. 这样您就知道注入并启动了内容脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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