You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React配置带nonce的CSP时脚本加nonce仍被拦截如何解决

问题根因

拦截是两个配置错误叠加导致的:

  • CSP指令存在语法错误:你写的script-src规则里,unsafe-inline没加单引号,浏览器根本识别不了这是CSP内置关键字,会直接把它当成无效的自定义主机源忽略。虽然现代浏览器在检测到nonce/hash校验规则时会自动忽略'unsafe-inline',但不支持strict-dynamic的老版本浏览器会因为没有有效内联脚本权限,直接拦截React打包产物里的内联runtime引导代码。
  • 构建工具没有配置nonce透传:React项目基本都是靠webpack/Rspack这类工具打包,运行时会动态生成三类标签:异步加载chunk的script标签、预加载资源的link标签、内联的runtime脚本。strict-dynamic规则只对「已经过CSP校验的受信任脚本,通过DOM API动态插入的script标签」生效,管不到link类型的预加载标签,也管不到构建时直接注入HTML的内联脚本;而且webpack默认不会给动态创建的标签自动携带当前页面的nonce,这些没带nonce的标签会直接被CSP拦下,最后表现为React打包的JS加载失败。
修复方案

按顺序调整配置即可:

  1. 修正CSP语法错误
    把script-src里漏了单引号的unsafe-inline改成'unsafe-inline',修正后的CSP参考:
    Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{0}' 'unsafe-eval' 'unsafe-inline'
    
    这里的'unsafe-inline'只是给不支持strict-dynamic的老浏览器做降级兼容,现代浏览器识别到nonce规则后会自动忽略这个配置,不会拉低安全等级。
  2. 配置构建工具全局透传nonce
    在React项目入口文件(一般是src/index.js)的最顶部加如下代码,让webpack给所有动态创建的script、link标签自动带上nonce:
    // 读取服务端注入的nonce值,不要硬编码在前端代码中
    const nonce = document.querySelector('meta[name="csp-nonce"]').content;
    // 配置webpack全局nonce
    __webpack_nonce__ = nonce;
    
    服务端渲染模板时,在HTML的head里加对应的meta标签存放每次请求生成的随机nonce:
    <meta name="csp-nonce" content="@nonce" />
    
  3. 检查内联脚本配置
    如果你在构建配置里开了runtimeChunk: 'inline'(把webpack runtime代码内联到HTML中),要给这段内联script标签也加上匹配的nonce属性,不能遗漏。

如果是用Create React App搭建的项目、没有eject配置,可以通过craco/react-app-rewired等自定义配置工具,配合csp-html-webpack-plugin实现构建时自动给所有script/link标签注入nonce,不用手动修改每个标签。
配置完可以打开浏览器控制台看CSP报错,如果还有拦截,根据报错提示的资源路径排查遗漏的未加nonce的标签即可。

内容的提问来源于stack exchange,提问作者Gal Algirdas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:33:20