You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展中设置为MAIN世界的内容脚本如何向后台脚本发送数据?

Chrome扩展中设置为MAIN世界的内容脚本如何向后台脚本发送数据?

你遇到的这个问题确实挺常见的——因为设置了world: "MAIN"的内容脚本运行在页面的主上下文里,这里没有Chrome扩展API的访问权限,所以chrome.runtime.sendMessage自然会返回undefined。不过别担心,我们可以通过自定义DOM事件+隔离世界内容脚本中转的方式来实现数据传递,具体做法如下:

核心思路

MAIN世界的脚本没法直接调用扩展API,但可以通过自定义DOM事件把数据传递给运行在「隔离世界」的内容脚本(这是Chrome扩展默认的内容脚本上下文,拥有完整的扩展API权限),再由隔离世界的脚本把数据转发给后台。

具体实现步骤

  1. 修改manifest.json,添加隔离世界的内容脚本
    在原有的MAIN世界内容脚本配置外,新增一个默认隔离世界的内容脚本:

    "content_scripts": [
        {
          "matches": ["<all_urls>"],
          "js": ["content-main.js"], // 原MAIN世界的脚本,重命名区分
          "run_at": "document_start",
          "world": "MAIN"
        },
        {
          "matches": ["<all_urls>"],
          "js": ["content-isolated.js"], // 新增的隔离世界脚本
          "run_at": "document_start"
        }
      ]
    
  2. 修改MAIN世界的脚本(content-main.js)
    把原来调用chrome.runtime.sendMessage的逻辑,换成触发自定义DOM事件,把数据放在事件的detail属性里:

    listenerFn = (event) => {
      const url = event.target.responseURL;
      if (url.startsWith("https://example.com/api/v2/home/allfeed")) {
        // 创建自定义事件并携带数据
        const transferEvent = new CustomEvent("forwardToBackground", {
          detail: {
            type: "response",
            data: event.target.responseText
          }
        });
        document.dispatchEvent(transferEvent);
      }
    };
    
    (() => {
      let XHR = XMLHttpRequest.prototype;
      let send = XHR.send;
      XHR.send = function () {
        this.addEventListener("load", listenerFn);
        return send.apply(this, arguments);
      };
    })();
    
  3. 编写隔离世界的中转脚本(content-isolated.js)
    监听自定义DOM事件,收到数据后调用chrome.runtime.sendMessage转发给后台:

    // 监听MAIN世界发来的自定义事件
    document.addEventListener("forwardToBackground", (event) => {
      // 调用扩展API发送数据到后台
      chrome.runtime.sendMessage(event.detail, (response) => {
        // 可选:处理后台的响应
        if (chrome.runtime.lastError) {
          console.error("发送数据失败:", chrome.runtime.lastError);
        } else {
          console.log("后台响应:", response);
        }
      });
    });
    

注意事项

  • 自定义事件的名称可以自行定义,只要两个脚本保持一致即可
  • 如果传递的是复杂数据(比如对象),要确保数据能被DOM事件正确序列化,避免出现循环引用等问题
  • 这种方式只会在你的扩展内部传递数据,不会被页面其他脚本监听(隔离世界的脚本和页面脚本是隔离的)

备注:内容来源于stack exchange,提问作者Amit Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 12:33:05