首页 文章

如何在chrome扩展中使用jQuery?

提问于
浏览
92

我正在写一个chrome扩展名 . 我想在我的扩展中使用 jQuery . 我没有使用任何背景页面,只是一个后台脚本 .

这是我的文件:

manifest.json

{
    "manifest_version": 2,

    "name": "Extension name",
    "description": "This extension does something,",
    "version": "0.1",

    "permissions": [
        "activeTab"
    ],

    "browser_action": {
        "default_icon": "images/icon_128.png"
    },

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

    "icons": {
        "16": "images/icon_16.png",
        "48": "images/icon_48.png",
        "128": "images/icon_128.png"
    }
}

我的 background.js 文件只运行另一个名为 work.js 的文件

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

我的扩展的主要逻辑是 work.js . 我认为这个问题的内容并不重要 .

我想问的是如何在扩展中使用jQuery . 因为我没有使用任何背景页面 . 我不能只是添加jQuery . 那么如何在我的扩展中添加和使用jQuery呢?

我尝试从 background.js 文件中运行jQuery和我的work.js .

// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript({
        file: 'thirdParty/jquery-2.0.3.js'
    });
    chrome.tabs.executeScript({
        file: 'work.js'
    });
});

并且它工作正常,但我担心添加以这种方式执行的脚本是否异步执行 . 如果是,则可能发生work.js甚至在jQuery(或我将来可能添加的其他库)之前运行 .

我还想知道在我的chrome扩展中使用第三方库的正确和最佳方式是什么 .

4 回答

  • 94

    您必须将您的jquery脚本添加到chrome-extension项目和manifest.json的 background 部分,如下所示:

    "background":
        {
            "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"]
        }
    

    如果在content_scripts中需要jquery,则必须在清单中添加它:

    "content_scripts": 
        [
            {
                "matches":["http://website*"],
                "js":["thirdParty/jquery.1.10.2.min.js", "script.js"],
                "css": ["css/style.css"],
                "run_at": "document_end"
            }
        ]
    

    这就是我做的 .

    此外,如果我没记错的话,后台脚本在后台窗口中执行,您可以通过 chrome://extensions 打开 .

  • 12

    它很容易做到以下几点:

    add the following line in your mainfest.json

    "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",
    

    现在你可以直接从url加载jquery

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    

    资料来源:google doc

  • 3

    它工作正常,但我担心添加以这种方式执行的脚本是否异步执行 . 如果是,则可能发生work.js甚至在jQuery(或我将来可能添加的其他库)之前运行 .

    这不应该是一个问题:您将脚本排队在某个JS上下文中执行,并且该上下文不能具有竞争条件,因为它是单线程的 .

    但是,消除这种担忧的正确方法是将呼叫链接起来:

    chrome.browserAction.onClicked.addListener(function (tab) {
        chrome.tabs.executeScript({
            file: 'thirdParty/jquery-2.0.3.js'
        }, function() {
            // Guaranteed to execute only after the previous script returns
            chrome.tabs.executeScript({
                file: 'work.js'
            });
        });
    });
    

    或者,概括:

    function injectScripts(scripts, callback) {
      if(scripts.length) {
        var script = scripts.shift();
        chrome.tabs.executeScript({file: script}, function() {
          if(chrome.runtime.lastError && typeof callback === "function") {
            callback(false); // Injection failed
          }
          injectScripts(scripts, callback);
        });
      } else {
        if(typeof callback === "function") {
          callback(true);
        }
      }
    }
    
    injectScripts(["thirdParty/jquery-2.0.3.js", "work.js"], doSomethingElse);
    

    或者,宣传(并使更多符合正确的签名):

    function injectScript(tabId, injectDetails) {
      return new Promise((resolve, reject) => {
        chrome.tabs.executeScript(tabId, injectDetails, (data) => {
          if (chrome.runtime.lastError) {
            reject(chrome.runtime.lastError.message);
          } else {
            resolve(data);
          }
        });
      });
    }
    
    injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}).then(
      () => injectScript(null, {file: "work.js"})
    ).then(
      () => doSomethingElse
    ).catch(
      (error) => console.error(error)
    );
    

    或者,为什么不是,为了更清晰的语法: async / await -ed

    function injectScript(tabId, injectDetails) {
      return new Promise((resolve, reject) => {
        chrome.tabs.executeScript(tabId, injectDetails, (data) => {
          if (chrome.runtime.lastError) {
            reject(chrome.runtime.lastError.message);
          } else {
            resolve(data);
          }
        });
      });
    }
    
    try {
      await injectScript(null, {file: "thirdParty/jquery-2.0.3.js"});
      await injectScript(null, {file: "work.js"});
      doSomethingElse();
    } catch (err) {
      console.error(err);
    }
    

    注意,在Firefox中你可以使用 browser.tabs.executeScript ,因为它会返回一个Promise .

  • 10

    除了已经提到的解决方案,您还可以在本地下载 jquery.min.js 然后使用它 -

    下载 -

    wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"
    

    manifest.json -

    "content_scripts": [
       {
        "js": ["/path/to/jquery.min.js", ...]
       }
    ],
    

    在HTML中 -

    <script src="/path/to/jquery.min.js"></script>
    

    参考 - https://developer.chrome.com/extensions/contentSecurityPolicy

相关问题