CSP 的 script-src 用 hash 为啥不生效?

欧阳馨翼 阅读 58

我在本地开发时给内联脚本加了 CSP hash,但浏览器还是报违反策略,明明 hash 是对的啊?

我用的是 Chrome,控制台显示:Refused to execute inline script because it violates the following Content Security Policy directive...。我用 openssl 算的 sha256,也去掉了 base64 填充的等号,格式应该没问题。

<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-xxxxxx'">
<script>
  console.log('hello');
</script>
我来解答 赞 24 收藏
二维码
手机扫码查看
2 条解答
公孙爱菊
说到CSP的hash问题,我也折腾过不少时间。首先你得注意几个坑。

内联脚本算hash时,<script>标签本身也要算进去。我之前就只算了里面的代码,结果怎么都不对。正确的hash应该是包含整个 <script>console.log('hello');</script> 这一整段。

然后是base64编码问题。虽然你说去掉了等号,但建议直接用浏览器开发者工具里的Network面板查看页面加载时的CSP头,确认是不是传输过程中被改了。Chrome有时候会自动调整。

给你个简单验证方法:先用在线工具生成正确的hash,替换进去试试。我常用这个网站 https://report-uri.com/home/hash 生成。

最后提醒一句,别在meta里写CSP,最好通过HTTP头部设置,兼容性更好。meta方式有些特殊情况可能会失效,别走弯路了。

<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-正确计算后的值'">
<script>console.log('hello');</script>


按照这个思路来,应该就能解决了。这种小细节确实容易踩坑,我都懂的。
点赞
2026-03-27 23:01
皇甫子璇
这个问题十有八九是空格或者换行符导致的。CSP 的 hash 校验是对脚本标签内的原始字节进行的,极其敏感,差一个空格、多一个回车,hash 都会变。

你用 openssl 算的时候,大概率没匹配上 HTML 文件里的实际内容。比如你的 script 标签里如果写了缩进,那你 openssl 的时候也得带上同样的缩进。还有个经典坑,echo 命令默认会在末尾加换行符,如果你没用 -n 参数,算出来的 hash 肯定跟浏览器对不上。

其实有个最简单粗暴的办法,不用自己算。你打开 Chrome 的控制台,仔细看那个 CSP 报错信息,里面其实已经告诉你它期望的 hash 是多少了,直接复制那个填到 meta 标签里,绝对好使。

如果你非要用命令行算,记得用 echo -n 并且把内容里的空格完全还原。比如像这样:

echo -n "  console.log('hello');" | openssl dgst -sha256 -binary | openssl enc -base64 -A


不过说实话,开发环境为了省事,直接加个 'unsafe-inline' 也就完事了,上线再改成 hash 或者 nonce。别在本地调 CSP 调到头秃,不值当。
点赞 1
2026-03-04 09:59