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

能否在Greasemonkey沙箱DOM中以@require方式加载ES6模块?

如何在Greasemonkey沙箱中以类似@require的方式加载ES6模块

针对Site B的CSP限制,以下是三种可行的ES6模块加载方案,均能在Greasemonkey沙箱中正常运行并访问本地数据库:

方案1:通过GM.xmlHttpRequest获取模块代码转Blob加载

利用GM的网络请求API获取模块内容,转为Blob URL后创建type="module"的脚本标签插入沙箱DOM,绕开CSP对外部资源的限制:

// ==UserScript==
// @name         Load ES6 Modules via GM.xmlHttpRequest
// @match        https://site-b.example.com/*
// @grant        GM.xmlHttpRequest
// ==/UserScript==

GM.xmlHttpRequest({
  method: "GET",
  url: "http://localhost/your-main-module.js", // 你的模块路径
  onload: (response) => {
    const moduleBlob = new Blob([response.responseText], { type: "text/javascript" });
    const moduleUrl = URL.createObjectURL(moduleBlob);
    
    const script = document.createElement("script");
    script.type = "module";
    script.src = moduleUrl;
    document.head.appendChild(script);

    // 模块加载完成后释放Blob资源
    script.onload = () => URL.revokeObjectURL(moduleUrl);
  }
});

如果模块有依赖,可在主模块内用import引入其他子模块(子模块需同样通过该方式加载,或打包为单文件)。

方案2:内联ES6模块代码

对于小型模块,直接将模块代码以字符串形式内联到脚本中,创建模块脚本插入沙箱:

// ==UserScript==
// @name         Inline ES6 Module in GM
// @match        https://site-b.example.com/*
// ==/UserScript==

// 你的ES6模块代码
const moduleCode = `
export async function fetchDBData() {
  return await fetch("http://localhost/db-api")
    .then(res => res.json());
}
`;

const script = document.createElement("script");
script.type = "module";
script.textContent = moduleCode;
document.head.appendChild(script);

// 调用模块导出的方法
script.onload = async () => {
  const module = await import(script.src);
  module.fetchDBData().then(data => console.log("数据库数据:", data));
};

方案3:用@resource声明模块资源

如果模块是本地文件,可通过@resource将其嵌入脚本,再用GM.getResourceText获取内容转为Blob加载:

// ==UserScript==
// @name         Load ES6 Module via @resource
// @match        https://site-b.example.com/*
// @resource     myModule http://localhost/your-module.js
// @grant        GM.getResourceText
// ==/UserScript==

const moduleText = GM.getResourceText("myModule");
const moduleBlob = new Blob([moduleText], { type: "text/javascript" });
const moduleUrl = URL.createObjectURL(moduleBlob);

const script = document.createElement("script");
script.type = "module";
script.src = moduleUrl;
document.head.appendChild(script);

script.onload = () => URL.revokeObjectURL(moduleUrl);

注意事项

  • 确保脚本声明了所需的@grant权限,比如GM.xmlHttpRequest或GM.getResourceText
  • 模块代码可直接调用Greasemonkey API,无需额外处理作用域
  • 多模块依赖场景建议打包为单文件,减少加载复杂度

内容的提问来源于stack exchange,提问作者FlamingKitties

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:42:15