如何在chrome扩展中使用jQuery?

Ish*_*han 111 javascript jquery asynchronous google-chrome google-chrome-extension

我正在写一个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"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

我的扩展的主要逻辑是在里面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'
    });
});
Run Code Online (Sandbox Code Playgroud)

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

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

Nic*_*ico 109

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

  "background":
    {
        "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"]
    }
Run Code Online (Sandbox Code Playgroud)

如果在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"
        }
    ]
Run Code Online (Sandbox Code Playgroud)

这就是我做的.

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

  • 那么你的意思是什么?你必须将你的jquery脚本添加到你的chrome扩展项目中吗?我这样做了:manifest.json:``background":{```scripts":["thirdParty/jquery-2.0.3.js","background.js"],```persistent":false``} ,`我已经将jQuery下载到thirdParty文件夹.但是我仍然无法使用jQuery.它给出了错误:`未捕获的ReferenceError:$未定义`我将此添加到我的`work.js`文件中进行测试.`$( "身体")HTML( "富!");` (5认同)
  • 我也很难让'jQuery`或`$`被识别出来.原来我在清单数组中最后引用了jQuery.当我把它放在第一位时它被认出来了. (5认同)
  • 我试着按照你说的去做。但是我仍然遇到同样的错误,无法从我的 `work.js` 文件访问 jquery。`未捕获的引用错误:$ 未定义`。如果可以,请您在某处上传一个工作示例。只是一个简单的例子,比如 '$("body").html("Foo!");' 在 work.js 中。 (2认同)

Vik*_*sal 16

它很容易做到以下几点:

在mainfest.json中添加以下行

"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",
Run Code Online (Sandbox Code Playgroud)

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

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

来源:谷歌文档


Xan*_*Xan 11

并且它工作正常,但我担心添加以这种方式执行的脚本是否异步执行.如果是,则可能发生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'
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

或者,概括:

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);
Run Code Online (Sandbox Code Playgroud)

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

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)
);
Run Code Online (Sandbox Code Playgroud)

或者,为什么没有,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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,在Firefox中,您可以使用browser.tabs.executeScript,因为它将返回Promise.


Ari*_*ani 7

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

对于下载-

wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"
Run Code Online (Sandbox Code Playgroud)

manifest.json-

"content_scripts": [
   {
    "js": ["/path/to/jquery.min.js", ...]
   }
],
Run Code Online (Sandbox Code Playgroud)

在html中-

<script src="/path/to/jquery.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

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

  • 这是最好的方法...您不需要html部分。 (2认同)