ChatGPT解决这个技术问题 Extra ChatGPT

如何在 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 扩展中使用第三方库的正确和最佳方式是什么。

正确的方法是去香草!
如果您在这里寻找如何将 jQuery 添加到弹出扩展中(就像我一样),请参阅以下问题:stackoverflow.com/questions/12035242/…

N
Nico

您必须将 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 打开的后台窗口中执行的。


那么您所说的 You have to add your jquery script to your chrome-extension project 到底是什么意思?我这样做了:manifest.json:"background": {`“scripts”:[“thirdParty/jquery-2.0.3.js”,“background.js”],`“persistent”:false``},`我已将 jQuery 下载到第三方文件夹。但是我仍然不能使用 jQuery。它给出了错误:Uncaught ReferenceError: $ is not defined 我将此添加到我的 work.js 文件中进行测试。 $("body").html("Foo!");
上面的评论看起来很乱,但是在添加评论时没有显示预览。请原谅我。
我的意思是将它添加到您的 chrome-extension 文件夹中。像 /home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js。你应该对你的 work.js 做同样的事情。
我试着按照你说的做。但我仍然遇到无法从我的 work.js 文件访问 jquery 的相同错误。 Uncaught ReferenceError: $ is not defined。如果可以,请在某处上传一个工作示例。只是一个简单的例子,比如 '$("body").html("Foo!");'在 work.js 中。
我也无法识别 jQuery$。原来我在清单数组中最后引用了 jQuery。当我把它放在第一位时,它就被认出来了。
V
Vikas Bansal

它非常容易,只需执行以下操作:

在 manifest.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


如果要加载多个脚本怎么办?
如果您想从远程服务器加载脚本(这实际上要求您信任远程服务器和您的扩展程序以及它可以访问的所有内容),这是一个很好的答案。
@NathanielVerhaaren 这是一个合理的问题,但可以通过使用 subresource integrity (SRI) 验证源来缓解。
它如何用于 backgroud.js 文件?
X
Xan

它工作正常,但我担心添加以这种方式执行的脚本是否正在异步执行。如果是,那么 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。


第一种方法很棒。作为一个不太了解 JavaScript 的人,我从来没有考虑过这样的事情。
A
Arik Pamnani

除了已经提到的解决方案,您还可以在本地下载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


这是最好的方法...您不需要 html 部分。
R
Ruslan Novikov

就我而言,通过跨文档消息传递 (XDM) 和执行 Chrome 扩展 onclick 而不是页面加载获得了一个可行的解决方案。

清单.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!')
        }
    }
);

A
Alberto Perez

从清单 3 开始,不允许使用匿名函数(在后台也不行)。 Jquery.js 文件通常具有匿名函数您应该为它们设置一个名称。


m
mariko

我手动下载了 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
|   ...