如何在 Chrome 扩展中使用 jQuery?

我正在写一个 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 扩展中,使用第三方库的正确和最好的方法是什么。

142439 次浏览

您必须像下面这样将 jquery 脚本添加到您的 chrome 扩展项目和 Manif.json 的 background部分:

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

如果您需要 content _ script 中的 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打开该窗口。

这很简单,只要做到以下几点:

添加以下代码行

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

资料来源: 谷歌文档

它工作得很好,但是我担心以这种方式添加的脚本是否是异步执行的。如果是,那么 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,因为它会返回一个。

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

下载-

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

宣言 Json

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

在 html-

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

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

在我的案例中,通过跨文档消息传递(XDM)得到了一个可行的解决方案 并执行 Chrome 扩展在点击而不是页面加载。

宣言 Json

{
"name": "JQuery Light",
"version": "1",
"manifest_version": 2,


"browser_action": {
"default_icon": "icon.png"
},


"content_scripts": [
{
"matches": [
"https://*.google.com/*"
],
"js": [
"jquery-3.3.1.min.js",
"myscript.js"
]
}
],


"background": {
"scripts": [
"background.js"
]
}


}

背景 Js

chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
});
});

Myscript.js

chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.message === "clicked_browser_action") {
console.log('Hello world!')
}
}
);

由于清单3,不允许匿名函数(在后台也不允许)。Js 文件通常具有匿名函数,您应该为它们设置一个名称。

我手动下载了 jquery 并将其像 javascript 文件一样导入到清单文件中。

maifest.json

"content_scripts": [
{
"matches": [...],
"js": ["jquery-3.6.0.min.js", ...],
}
]

folder sructure

extension
│   manifest.json
│   jquery-3.6.0.min.js
|   ...