agGrid React v33.0.4部署后CSS失效,遭遇Content Security Policy拦截问题求助
我目前在React 18项目里使用agGrid v33.0.4,本地运行时一切正常,agGrid的样式显示完全没问题,但部署到生产环境后,agGrid的CSS完全不生效,界面变得杂乱(效果见下图)。

打开浏览器控制台,能看到一堆类似这样的报错:
index-CVD4k8Nb.js:262 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='". Either the 'unsafe-inline' keyword, a hash ('sha256-ARh575sf3Q/vXFopOXpb2rkaSl8BXcDZ7zLP3cYtFMU='), or a nonce ('nonce-...') is required to enable inline execution.
我查了agGrid的官方文档,说可以通过在GridOptions里配置styleNonce来解决这个CSP拦截问题,于是我在代码里加了这段:
const gridOptions = { // 其他配置项 styleNonce: "416d1177" // 这里用generateGUID()生成的随机值 }
结果控制台又弹出了新的错误:
hook.js:608 AG Grid: invalid gridOptions property 'styleNonce' did you mean any of these: suppressLastEmptyLineOnPaste, includeHiddenColumnsInQuickFilter, includeHiddenColumnsInAdvancedFilter, stopEditingWhenCellsLoseFocus, enableCellEditingOnBackspace, onChartRangeSelectionChanged, onGridStylesChanged, selectionColumnDef.
补充说明一下:部署后的项目里agGrid的CSS文件是已经正确引入的,我用开发者工具查看页面源码,能在标签里看到agGrid的样式文件。
(几周后补充)
虽然有不少人提议关闭这个问题,但我还是想把最终的解决方案分享出来,帮到可能遇到同样坑的朋友(因为问题被标记为关闭,我没法单独发布回答)。
问题根源
其实问题出在我们公司生产环境的Content-Security-Policy配置上,其中style-src的限制非常严格:
<add name="Content-Security-Policy" value="default-src 'self' script-src 'self' 'sha256-Ve/gCBicgW5xxxxxxxx2OAqdU=' img-src 'self' blob: data:; style-src 'self' 'sha256-47DEQpxxxx" />
这就是为什么本地运行不受影响,但部署后agGrid的样式就被拦截了。
解决办法
后来agGrid的技术支持回复了我,他们给出的正确配置方式是全局设置styleNonce:
provideGlobalGridOptions({ styleNonce: 'F038Axxxx32A08' });
我需要做的就是添加这段代码,然后把这个(我暂时硬编码的)styleNonce值添加到Content-Security-Policy的配置项里。
这里要提一句:规范做法应该是每次请求生成唯一的nonce值。我试过用React Helmet在页面刷新时生成新的GUID并更新CSP的meta标签,虽然能成功生成,但时机太晚了——浏览器在解析里的CSP规则时,agGrid的样式已经被拦截了,所以这个动态生成的方案没生效。
agGrid还提供了另一个备选方案:使用旧版样式体系。也就是设置theme='legacy',采用v32版本的主题CSS文件,这样agGrid会加载静态CSS文件,不会再产生内联样式,也就不会触发CSP的拦截了。
我们最终选择了硬编码固定nonce值的方案,网站的agGrid样式就恢复正常了。
备注:内容来源于stack exchange,提问作者Mike Gledhill




