Chrome扩展Manifest V3下注入内置脚本触发CSP报错如何解决
Manifest V3 Chrome扩展注入页面上下文脚本解决方案
错误原因
Manifest V3 对扩展的内容安全策略做了强制约束,extension_pages 域下的 script-src 指令不允许使用 'unsafe-inline'、哈希值、nonce 这类会降低安全等级的配置,因此修改CSP添加上述配置的操作都会被浏览器拦截报错,该路径不可行。
可行方案
方案1:使用MAIN世界内容脚本(推荐,Chrome 111+ 支持)
该方案无需手动插入script标签,通过Chrome官方提供的上下文配置直接让内容脚本运行在页面的执行上下文,可直接重写fetch等全局API,完全避开CSP限制。
在manifest.json中添加如下配置:
{ "manifest_version": 3, "name": "你的扩展名称", "version": "1.0", "content_scripts": [ { "matches": ["<all_urls>"], // 按需替换为你要注入的页面匹配规则 "js": ["inject.js"], // 存放重写fetch逻辑的脚本文件 "world": "MAIN", // 关键配置:指定脚本运行在页面主上下文 "run_at": "document_start" // 页面DOM加载前注入,保证重写逻辑先于页面代码执行 } ] }
直接在inject.js中编写重写逻辑即可,例如:
// 重写fetch示例 const originalFetch = window.fetch; window.fetch = function(...args) { console.log('拦截到fetch请求', args); return originalFetch.apply(this, args); };
方案2:插入扩展静态脚本文件(兼容低版本Chrome)
如果需要兼容Chrome 111之前的版本,可以通过插入指向扩展静态资源的script标签实现,不会触发inline脚本的CSP报错:
- 首先在
manifest.json中声明要注入的脚本为可公开访问的资源:
{ "manifest_version": 3, "web_accessible_resources": [ { "resources": ["inject.js"], // 要注入的脚本文件路径 "matches": ["<all_urls>"] // 允许访问该资源的页面匹配规则 } ], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], // 负责插入script标签的内容脚本 "run_at": "document_start" } ] }
- 在
content.js中编写插入脚本的逻辑:
const injectScript = document.createElement('script'); injectScript.src = chrome.runtime.getURL('inject.js'); // 脚本加载完成后移除标签避免污染DOM injectScript.onload = () => injectScript.remove(); (document.head || document.documentElement).prepend(injectScript);
内容的提问来源于stack exchange,提问作者Ivan Rusinov
相关产品推荐
相关产品推荐

