How do I inject certain files into certain websites from a chrome extension

后端 未结 2 2025
醉酒成梦
醉酒成梦 2021-01-15 19:56

In my chrome extension I have multiple files that inject script into websites, I want to know how I can inject 1 file for a certain website. To better explain

My chr

相关标签:
2条回答
  • 2021-01-15 20:33

    Use the Tampermonkey / Greasemonkey extensions, with the header like that:

    // ==UserScript==
    // @name         MTV Statistical Data For Tampermonkey & Greasemonkey
    // @namespace    MTV_statistical_data
    // @include     /^https?://(www\.)?mytrafficvalue\.com/shareholders\.html(\#marketplace)?$/
    // @author       facebook.com/igor39
    // @version      7.5
    // @grant        none
    // @description  Improving the user experience & provide more of statistics on the page www.mytrafficvalue.com/shareholders.html
    // ==/UserScript==
    

    Example: http://pastebin.com/Z4zq2h6Q

    0 讨论(0)
  • 2021-01-15 20:41

    Injecting JavaScript files is done either through an entry in the content_scripts key in your manifest.json, or through chrome.tabs.executeScript().

    Using chrome.tabs.executeScript()

    You should use chrome.tabs.executeScript() if you don't need your script injected every single time the matching URL is loaded. This is particularly the case when interaction with your extension begins with the user clicking on a browserAction, or pageAction button.

    Given that chrome.tabs.executeScript() is a direct JavaScript API call, I am going to assume that you understand how to make a choice as to what to inject based on the URL from the tab.url property.

    Injecting stackContent.js could look like:

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

    Injecting both jquery.js and stackContent.js could look like:

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

    You should also be checking for errors reported by chrome.runtime.lastError. A function I use for doing so in both Chrome and Firefox WebExtensions is:

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

    Using the content_scripts key in manifest.json

    In your manifest.json you have a content_scripts key which describes scripts or CSS that are always injected into matching URLs. You should use this if you need a script, or CSS to be always injected into matching URLs.

    While it might be more convenient to always have your script injected, you should seriously consider not doing so unless it is needed. You should particularly stay away from doing so if you are loading large scripts and/or on a large number of websites (e.g. all URLs). Indiscriminately injecting your script(s) (including libraries) on a large number of websites can take significant resources on the user's computer which can cause a loss of performance, affecting user experience. If you need to have interaction begin from within the website, try loading a smaller script that waits for that interaction to begin, then messages your background script to inject the rest of your functionality. Sometimes you do need your script loaded all the time, but try to think about it from your user's perspective, not just what is convenient in writing your extension. As an example of going too far injecting scripts using content_scripts, the extension about which this question was asked injects 78 different scripts into every https:// page.

    The content_scripts key contains an array of objects. Each object describes a single injection directive. The object can contain multiple conditions and multiple files, but each one is all-or-nothing; either all files described in that object are injected, or none, depending on if the URL matches. If you want some file(s) injected to some URLs and some other file(s) injected to other URLs, then you use separate Objects to describe each group.

    An example, which injects jquery.js & stackContent.js into Stack Exchange sites and jquery.js & exampleContent.js into example.com is:

    "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"]
        }
    ]
    

    Permissions

    Depending on what you are doing, you are going to need permissions to interact with the matching URLs you are interested in and/or use chrome.tabs. From the above examples:

    "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/*"
    ]
    
    0 讨论(0)
提交回复
热议问题