javascript - 如何从 chrome 扩展程序将某些文件注入(inject)某些网站

标签 javascript google-chrome-extension

在我的 chrome 扩展程序中,我有多个将脚本注入(inject)网站的文件,我想知道如何为某个网站注入(inject) 1 个文件。为了更好地解释

我的 chrome 扩展程序有 1 个文件要注入(inject) Github和另一个文件注入(inject)到不同的网站如何将每个文件注入(inject)到他们自己的网站而不将两个文件都注入(inject)到每个网站。所以每个文件都会被注入(inject)到他们自己的网站。

最佳答案

注入(inject) JavaScript 文件是通过 content_scripts 中的条目完成的。键入您的 manifest.json ,或通过 chrome.tabs.executeScript() .

使用 chrome.tabs.executeScript()

如果您不需要每次加载匹配的 URL 时注入(inject)脚本,您应该使用 chrome.tabs.executeScript()。当与您的扩展程序的交互始于用户单击 browserAction 时,情况尤其如此。 , 或 pageAction按钮。

鉴于 chrome.tabs.executeScript() 是一个直接的 JavaScript API 调用,我假设您了解如何根据来自tab.url属性(property)。

注入(inject) stackContent.js 可能如下所示:

chrome.tabs.executeScript(tabId,{
    file: "stackContent.js"
}, result => {
    handleExecuteScriptAndInsertCSSErrors(tabId);
});

注入(inject) jquery.jsstackContent.js 看起来像:

chrome.tabs.executeScript(tabId,{
    file: "jquery.js"
}, result1 => {
    handleExecuteScriptAndInsertCSSErrors(tabId);
    chrome.tabs.executeScript(tabId,{
        file: "stackContent.js"
    }, result2 => {
        handleExecuteScriptAndInsertCSSErrors(tabId);
    });
});

您还应该检查 chrome.runtime.lastError 报告的错误.我在 Chrome 和 Firefox WebExtensions 中使用的一个函数是:

function handleExecuteScriptAndInsertCSSErrors(tabId) {
    if(chrome.runtime.lastError) {
        let message = chrome.runtime.lastError.message;
        let isFirefox = !!window.InstallTrigger;
        let extraMessage = tabId ? 'in tab ' + tabId + '.' : 'on this page.';
        if((!isFirefox && message.indexOf('Cannot access a chrome:') > -1) //Chrome
            || (isFirefox && message.indexOf('No window matching') > -1) //Firefox
        ) {
            //The current tab is one into which we are not allowed to inject scripts.
            //  This is most likely because we are injecting based on a action button
            //  click. You should disable the action button when a tab is active on
            //  which you can not perform the task that is expected by the user.
            let messageText= 'This extension, ' + chrome.runtime.id
                             + ', does not work ' + extraMessage;
            //alert(messageText); //Use for testing
            console.log(messageText);
        } else {
            //Report the error
            if(isFirefox) {
                //In Firefox, runtime.lastError is an Error Object including a stack trace.
                console.error(chrome.runtime.lastError);
            } else {
                console.error(message);
            }
        }
    }
}

使用 manifest.json 中的 content_scripts

在您的 manifest.json 中,您有一个 content_scripts 键,它描述始终注入(inject)匹配 URL 的脚本或 CSS。如果您需要将脚本或 CSS 始终注入(inject)匹配的 URL,则应使用它。

虽然始终注入(inject)脚本可能更方便,但您应该认真考虑不这样做,除非需要。如果您正在加载大型脚本和/或在大量网站(例如所有 URL)上,您尤其应该避免这样做。在大量网站上随意注入(inject)您的脚本(包括库)会占用用户计算机上的大量资源,从而导致性能下降,影响用户体验。如果您需要从网站内部开始交互,请尝试加载一个较小的脚本来等待交互开始,然后向您的后台脚本发送消息以注入(inject)您的其余功能。有时您确实需要一直加载脚本,但请尝试从用户的 Angular 考虑,而不仅仅是编写扩展的方便之处。作为使用 content_scripts 过度注入(inject)脚本的示例,this question was asked 的扩展名将 78 个不同的脚本注入(inject)到每个 https:// 页面。

content_scripts 键包含一个对象数组。每个对象都描述了一个注入(inject)指令。对象可以包含多个条件和多个文件,但每一个都是全有或全无;要么注入(inject)该对象中描述的所有文件,要么不注入(inject),具体取决于 URL 是否匹配。如果您希望将一些文件注入(inject)到某些 URL 并将一些其他文件注入(inject)到其他 URL,那么您可以使用单独的对象来描述每个组。

一个示例,它将 jquery.jsstackContent.js 注入(inject) Stack Exchange 站点和 jquery.jsexampleContent。 jsexample.com 是:

"content_scripts": [
    {
        "matches": [
            "http*://*.askubuntu.com/*",
            "http*://*.mathoverflow.net/*",
            "http*://*.serverfault.com/*",
            "http*://*.stackapps.com/*",
            "http*://*.stackexchange.com/*",
            "http*://*.stackoverflow.com/*",
            "http*://*.superuser.com/*"
        ],
        "js": ["jquery.js", "stackContent.js"]
    },
    {
        "matches": ["http*://*.example.com/*"],
        "js": ["jquery.js", "exampleContent.js"]
    }
]

权限

根据您正在做的事情,您将需要权限才能与您感兴趣的匹配 URL 进行交互和/或使用 chrome.tabs。从上面的例子:

"permissions": [
    "tabs",
    "http*://*.askubuntu.com/*",
    "http*://*.mathoverflow.net/*",
    "http*://*.serverfault.com/*",
    "http*://*.stackapps.com/*",
    "http*://*.stackexchange.com/*",
    "http*://*.stackoverflow.com/*",
    "http*://*.superuser.com/*",
    "http*://*.example.com/*"
]

关于javascript - 如何从 chrome 扩展程序将某些文件注入(inject)某些网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40516878/

相关文章:

javascript - 无法查找 View Node JavaScript

javascript - 为什么这个 javascript 在 Chrome 中执行,但在 Firefox 中却不行?

javascript - 从 chrome 扩展中注入(inject)函数/变量到页面

javascript - Chrome 扩展 - 执行前修改脚本

javascript - 如何无限重复javascript setInterval计时器两次

javascript - Fabric.js 对象大小

javascript - 我如何为图表 js 使用内联插件内部标题?

google-chrome - 如何为 Google Chrome 扩展创建安装程序

javascript - 如何仅在特定链接上运行background.js?

javascript - Chrome扩展中的POST请求数据和地址栏更改