Vue.js+Express全栈应用部署Heroku出现Content Security Policy错误如何解决
问题原因分析
eval脚本被阻止:生产环境默认内容安全策略(CSP)禁止执行eval类动态脚本,触发原因通常有两类:一是Vue项目生产构建配置的devtool设为了eval相关取值,打包后代码包含eval逻辑;二是项目依赖的第三方库使用了动态eval执行代码。- 本地接口请求被阻止:前端API请求的基础地址写死为
http://localhost:3000,部署到Heroku后线上环境不存在该本地服务,同时CSP默认禁止页面请求未被许可的跨域/本地地址。
解决方案
修复eval被拦截问题
- 调整Vue打包配置,生产环境关闭含eval的sourcemap生成:
// vue.config.js(vue-cli项目) module.exports = { productionSourceMap: false, configureWebpack: { devtool: process.env.NODE_ENV === 'production' ? false : 'eval-cheap-module-source-map' } }
- 若排查为第三方依赖使用eval,可在Express服务端配置CSP响应头允许eval执行,该中间件需放在静态资源服务逻辑之前:
app.use((req, res, next) => { res.setHeader( 'Content-Security-Policy', "script-src 'self' 'unsafe-eval'; default-src 'self' https://*;" ); next(); });
修复接口请求被拦截问题
- 修改前端API请求配置,根据环境动态拼接基础地址,不要写死localhost:
// axios 全局配置示例 const request = axios.create({ baseURL: process.env.NODE_ENV === 'production' ? '/api/v1' : 'http://localhost:3000/api/v1' })
- 调整Express路由注册顺序,API路由要放在静态资源服务逻辑之前,避免被
*通配路由拦截:
// 先注册API路由 app.use('/api/v1', 你的接口路由实例); // 再处理前端静态资源 if (process.env.NODE_ENV === "production") { app.use(express.static(__dirname + "/dist/")); app.get("*", (req, res) => { res.sendFile(__dirname + "/dist/index.html"); }); }
- 额外注意:Express启动时不要写死监听端口,要读取Heroku自动分配的端口环境变量:
const PORT = process.env.PORT || 3000; app.listen(PORT);
内容的提问来源于stack exchange,提问作者lizardcoder
相关产品推荐
相关产品推荐

