【问题标题】:Chrome extension, best way to send messages from injected script to backgroundChrome 扩展,将消息从注入脚本发送到后台的最佳方式
【发布时间】:2019-04-16 18:59:09
【问题描述】:

我正在尝试设计一个chrome扩展,它必须在网页中注入一个脚本,这个脚本拦截json响应,并将它们发送到后台脚本。

请记住,我不习惯 js,我可能做错了,所以,在我的清单中我有:

"background": {
    "scripts": ["background.js"],
    "persistent": true
},
"content_scripts": [
{
  "matches": ["*://url*"],
  "run_at": "document_start",
  "js": ["inject.js"]
}
],
"web_accessible_resources": ["injected.js"],

在我的后台脚本中,我以这种方式处理消息:

 chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.type) {
        switch(request.type) {
            case "THIS_REQUEST_TYPE":
            do_stuff(request.foo, request.bar);
            break;
            ...................

inject.js 的目的是将injected.js 注入到一个网页中,现在它也在做从injected.js 到background.js 的消息的中继,我是这样注入injected.js 的:

    var s = document.createElement('script');
s.src = chrome.extension.getURL('injected.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

现在,要从 injection.js 获取消息到我的后台脚本,我基本上使用:

  window.postMessage(msgdata, "*");

这会将消息从inject.js 发送到inject.js,然后在inject.js 中我可以使用:

 window.addEventListener("message", function(event) {

然后我终于可以将这些消息发送到我的后台脚本,这次使用:

chrome.runtime.sendMessage(

我发现无法将消息从inject.js 直接发送到background.js,chrome 文档中提供的信息非常适合将消息从inject.js 发送到background.js,但不能正常工作,我尝试了几种在线解决方案,我使用的是唯一一种我能够开始工作的解决方案。

无论如何,这行得通,我可以将json响应从inject.js发送到inject.js到background.js并在我的后台脚本中解析它们。

问题是,我讨厌这样做,json 响应可能真的很长,我已经在 inject.js 中过滤响应,这样只有有用的才会被发送,但有时我还是必须这样做发送 591109 个字符长的响应副本! 所以,必须发送两次这么长的响应有点难看,我希望这既高效又快速。

有人对此有想法吗?

【问题讨论】:

    标签: javascript google-chrome-extension messaging


    【解决方案1】:

    您的 injection.js 在 script DOM 元素中运行,因此它只是一个非特权网页脚本。要直接从网页脚本中使用 chrome.runtime.sendMessage,您必须在 externally_connectable 中声明允许的 URL 模式,但您不能不加选择地允许所有 URL,所以我会使用您的方法,尽管使用 CustomEvent(和随机事件名称最有可能)而不是 message 可以被页面脚本或其他扩展拦截 - 这不是我在这里关心的安全性,而是有可能破坏假设消息数据在某个站点中的某些站点格式(例如字符串),与您使用的格式(例如对象)不兼容。

    您还可以使用 chrome.debugger API 附加到选项卡并在后台脚本中拦截 JSON 响应,但这会在选项卡上方显示一个关于它正在调试的通知。

    无论如何,除非您看到您的扩展程序减慢了页面速度(在 devtools 分析器中或通过手动测量代码花费的时间),否则无需担心。

    FWIW,在 Firefox 中,您可以直接通过 browser.webRequest.filterResponseData 阅读响应。

    【讨论】:

    • 对于基于CustomEvent 的通信示例:stackoverflow.com/a/25847017/934239
    • 太棒了!实际上, externally_connectable 中允许的 URL 可能是一个很好的解决方案。我知道使用调试器 api 的可能性,虽然我没有尝试,但我担心会使用太多资源。
    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    相关资源
    最近更新 更多