设置安全头后页面白屏,CSP策略哪里写错了?

公孙紫瑶 阅读 2

我在 Express 项目里加了 Content-Security-Policy 头,想限制只加载本地资源,但页面直接白屏了,控制台报错说脚本被阻止。我明明没引用外部 JS 啊,难道是内联脚本的问题?

尝试过加上 ‘unsafe-inline’,但听说这样不安全就没用。现在卡在这儿不知道咋调,求指点 CSP 到底该怎么配才既安全又不崩页面。

app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self';"
  );
  next();
});
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
瑞芳(打工版)
你遇到的问题很简单:CSP 默认会阻止所有内联脚本执行,就是 这种,哪怕你没有外部引用,浏览器本身、某些框架(比如React开发模式)、热更新模块都可能偷偷注入内联脚本。

先确认问题是不是内联脚本导致的,临时加上 unsafe-inline 试试:

app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' 'unsafe-inline';"
);
next();
});


加上之后页面能正常显示的话,那肯定就是内联脚本的问题。

如果你想既安全又不加 unsafe-inline,有两个思路:

一是把内联脚本抽成外部JS文件,这是最干净的做法。

二是用 nonce 方式,只允许特定的内联脚本运行:

const crypto = require('crypto');

app.use((req, res, next) => {
const nonce = crypto.randomBytes(16).toString('base64');
res.setHeader(
'Content-Security-Policy',
default-src 'self'; script-src 'self' 'nonce-${nonce}';
);
res.locals.nonce = nonce;
next();
});


然后在你的HTML模板里给内联脚本加上这个nonce:



这样只有带正确nonce的内联脚本能跑,比 unsafe-inline 安全多了。

不过说实话,如果你这只是个小项目或者内部系统,加 unsafe-inline 也无妨,别把 default-src 设成 * 就行。搞太复杂反而给自己找麻烦。
点赞
2026-03-13 20:09