Vue3+Node/Express部署后页面刷新触发CSP EvalError求助
Vue 3 + Express 部署刷新页面触发 CSP 'unsafe-eval' 错误的安全解决方案
问题重现
部署 Vue 3 + Node/Express 构建后的前端代码时,页面刷新会抛出以下错误:
EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'"
at new Function (<anonymous>) ...etc
首次加载页面无异常,仅刷新时触发。需要避免添加'unsafe-eval'到CSP头,也不想移除helmet.js,寻求安全替代方案。
解决方案
1. 调整 Vue 3 构建配置,禁用依赖new Function()的特性
Vue 3 生产构建时的某些优化或sourcemap生成逻辑会用到new Function(),修改构建配置可以规避:
- 如果用 Vite,在
vite.config.js中添加:export default { build: { rollupOptions: { output: { generatedCode: { constBindings: true, preset: 'es2015' } } }, // 禁用依赖eval的sourcemap类型,或直接关闭sourcemap sourcemap: 'hidden' } } - 如果用 Vue CLI,修改
vue.config.js:module.exports = { configureWebpack: { output: { generatedCode: { constBindings: true, preset: 'es2015' } }, devtool: 'hidden-source-map' // 或设置为false完全关闭sourcemap } }
2. 优化 Helmet.js 的 CSP 配置,添加必要的合法脚本源
不需要开放unsafe-eval,只需确保CSP包含Vue 3运行必需的指令:
在Express的Helmet配置中修改CSP:
const helmet = require('helmet'); app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], // Vue 3 hydration过程需要inline脚本支持,比unsafe-eval安全 styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:"], fontSrc: ["'self'"] } }));
'unsafe-inline'的风险远低于unsafe-eval,因为inline脚本是你自己代码的一部分,可控性强。
3. 确认SPA路由 fallback 配置正确
刷新页面出错常和SPA路由配置有关,要确保Express将所有路由请求转发到index.html:
const path = require('path'); // 托管静态资源 app.use(express.static(path.join(__dirname, 'dist'))); // SPA路由 fallback:所有非静态资源请求都返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); });
配置错误会导致刷新时加载错误资源,触发异常脚本执行逻辑。
4. 排查第三方依赖是否使用eval
检查项目依赖中是否有调用eval或new Function()的包,执行以下命令扫描:
npm ls | grep -E 'eval|function-constructor'
找到后替换为无eval的替代包,或者联系包作者修复问题。
内容的提问来源于stack exchange,提问作者user14131782
相关产品推荐
相关产品推荐

