该错误源于浏览器CSP策略拦截eval,需按环境精准处理:普通网页可临时放宽策略;Manifest V2可在manifest.json中配置'unsafe-eval';Manifest V3则必须重构代码禁用运行时编译。

遇到 Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source 错误,本质不是 eval 本身坏了,而是浏览器(尤其是 Chrome 扩展环境)用 CSP 策略主动拦下了它。解决的关键不在于“绕过”或“禁用安全”,而在于明确场景、匹配策略、精准调整——该放行的放行,该重构的重构。
先确认你处在什么环境
不同环境,解法完全不同,不能一概而论:
-
普通网页(非扩展):可通过 HTTP 响应头
Content-Security-Policy: script-src 'self' 'unsafe-eval'或 HTML 的<meta>标签临时放宽,但仅限开发调试,上线必须移除; -
Chrome 扩展 Manifest V2:支持在
manifest.json中配置content_security_policy显式启用'unsafe-eval'; -
Chrome 扩展 Manifest V3:
'unsafe-eval'被彻底禁止,任何尝试添加都会被忽略,必须改代码; -
Firefox 开发调试:可临时关闭 CSP(
about:config → security.csp.enable = false),但仅限本地验证,不影响生产行为。
针对 Chrome 扩展 V2:安全地启用 unsafe-eval
如果你确定使用的是 Manifest V2,且选项页、弹出页等需要 Vue/React 运行时编译,可在 manifest.json 中这样写:
{"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"}
注意三点:
- 只对
extension_pages(如 options.html、popup.html)生效,content_scripts和background不受此字段影响; - 不要加
'unsafe-inline',除非你真有内联脚本且已评估风险; - 确保所有 JS 都来自
'self'(即扩展包内),不加载外部 CDN 脚本,否则仍会报错。
针对 Chrome 扩展 V3:必须重构,无法妥协
Manifest V3 下,'unsafe-eval' 是硬性禁令。Vue/React 报错,通常是因为用了开发版构建(含运行时模板编译器)。正确做法是:
- Vue 项目:用
vue-cli或vite build --mode production构建,确保使用 runtime-only 版本(vue.runtime.esm-bundler.js),模板必须预编译为 render 函数; - React 项目:禁用
eval-based HMR,使用@pmmmwh/react-refresh-webpack-plugin替代,或直接切换到 Vite + React 插件模板; - 手动替换动态执行逻辑:把
eval(str)改成JSON.parse(str)(仅限 JSON 字符串),把setTimeout("doSomething()", 100)改成setTimeout(doSomething, 100); - 沙盒页面(sandbox):对确实需要动态执行的模块(如用户自定义规则引擎),可单独声明一个沙盒 HTML,在 manifest 中配置
sandbox字段,沙盒内 CSP 更宽松,且与主页面完全隔离。
调试阶段快速验证是否 CSP 导致
不用反复打包,几个低成本方法可快速定位:
- 打开开发者工具 → Application → Manifest,查看当前生效的 CSP 策略字符串;
- 在 Console 中执行
document.querySelector('meta[http-equiv="Content-Security-Policy"]')(网页)或检查扩展页面响应头; - 用 Chrome 扩展 CSP Disable 一键临时关闭当前页 CSP,若错误消失,即可 100% 确认是 CSP 问题;
- 在 background script 中故意写
eval('console.log(1)'),看是否同样报错——若报错,说明 CSP 全局生效;若不报错,说明问题只出在 extension_pages 上下文。

















