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

如何在通过browser.scripting.executeScript执行的匿名脚本中访问browser对象并向扩展后台发送消息?

如何在通过browser.scripting.executeScript执行的匿名脚本中访问browser对象并向扩展后台发送消息?

嘿,你遇到的这个问题其实是浏览器上下文隔离导致的——你在MAIN世界注入的脚本是跑在网页自己的上下文里,而browser对象属于扩展专属的隔离上下文(也就是ISOLATED世界),所以在网页上下文里直接拿不到它,而且你也没法把browser对象作为参数传过去,因为它包含很多不能被序列化的方法和属性,跨边界传递会直接失效。

给你一个实用且符合安全规则的解决思路:

用自定义DOM事件做上下文桥接

这是最常用的方式,核心逻辑是让MAIN世界的脚本把拦截到的数据通过自定义事件发给ISOLATED世界,再由ISOLATED世界的脚本调用扩展API发消息到后台。

具体代码可以这么改:
首先,先在隔离上下文注入一个监听脚本,负责接收事件并转发消息:

// 先注入隔离上下文的监听脚本
await browser.scripting.executeScript({
  target: details,
  world: "ISOLATED",
  injectImmediately: true,
  func: () => {
    // 监听来自MAIN世界的自定义事件
    window.addEventListener("pushStateIntercepted", (e) => {
      const { state, unused, url } = e.detail;
      // 这里可以正常使用browser对象
      browser.runtime.sendMessage({
        type: "safari-onhistorystateupdated",
        state,
        unused,
        url
      });
    });
  }
});

然后再注入你原来的MAIN世界拦截脚本,把原来调用browser.runtime.sendMessage的地方改成发送自定义事件:

// 注入MAIN世界的拦截脚本
await browser.scripting.executeScript({
  target: details,
  world: "MAIN",
  injectImmediately: true,
  args: [tabId, frameId],
  func: (tabId, frameId) => {
    if (window.history.__pushState) {
      console.warn("Already injected");
      return;
    }
    window.history.__pushState = history.pushState;
    console.log("Injected pushState()");
    history.pushState = function(state, unused, url) {
      console.log("Intercepted pushState()", state, unused, url);
      window.history.__pushState(state, unused, url);
      // 创建自定义事件并传递数据
      const event = new CustomEvent("pushStateIntercepted", {
        detail: { state, unused, url }
      });
      window.dispatchEvent(event);
    };
  }
});

另外提醒一下,不要尝试用直接传递browser对象或者在MAIN世界调用chrome.runtime.sendMessage的方式——前者会因为序列化失效,后者属于非标准行为,不同浏览器兼容性差异很大,很容易出问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:10:28