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

Tampermonkey脚本import模块违反CSP指令如何解决?

解决Tampermonkey脚本中导入ESM模块的CSP限制问题

问题根源

目标网站(知乎)的**内容安全策略(CSP)**限制了脚本加载来源,禁止从esm.sh域名加载脚本,直接使用import()或通过GM_addElement添加模块类型脚本都会触发CSP拦截。


可行解决方案

方案1:通过GM_xmlhttpRequest获取模块代码,用Blob URL注入

利用Tampermonkey的GM_xmlhttpRequest不受页面CSP限制的特性,拉取模块代码后转换为Blob URL注入(知乎CSP允许blob:来源):

// ==UserScript==
// @name         xxxxxx
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @include      *://*.zhihu.com/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

GM_xmlhttpRequest({
  method: 'GET',
  url: 'https://esm.sh/octokit',
  responseType: 'text',
  onload: (res) => {
    // 将模块代码转为Blob对象
    const blob = new Blob([res.responseText], { type: 'application/javascript' });
    const blobUrl = URL.createObjectURL(blob);

    // 注入模块脚本
    const moduleScript = document.createElement('script');
    moduleScript.type = 'module';
    moduleScript.src = blobUrl;

    // 模块加载完成后执行业务逻辑
    moduleScript.onload = () => {
      const usageScript = document.createElement('script');
      usageScript.type = 'module';
      usageScript.textContent = `
        import { Octokit, App } from '${blobUrl}';
        // 这里编写你的业务代码
        const octokit = new Octokit();
        console.log('Octokit 加载完成:', octokit);
      `;
      document.head.appendChild(usageScript);
      URL.revokeObjectURL(blobUrl); // 释放Blob资源
    };

    document.head.appendChild(moduleScript);
  }
});

方案2:导入打包后的IIFE版本模块

使用esm.sh的打包功能,将模块转换为IIFE格式(自动挂载到全局window对象),避免模块类型脚本的CSP限制:

// ==UserScript==
// @name         xxxxxx
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @include      *://*.zhihu.com/*
// @grant        GM_addElement
// ==/UserScript==

// 导入打包后的IIFE版本,模块会挂载到window
GM_addElement('script', {
  src: 'https://esm.sh/octokit?bundle',
  type: 'text/javascript'
});

// 等待脚本加载完成后使用模块
window.addEventListener('load', () => {
  const { Octokit, App } = window;
  const octokit = new Octokit();
  console.log('Octokit 加载完成:', octokit);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:10:35