You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

agGrid React v33.0.4部署后CSS失效,遭遇Content Security Policy拦截问题求助

agGrid React v33.0.4部署后CSS失效,遭遇Content Security Policy拦截问题求助

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

agGrid部署后无样式显示效果

打开浏览器控制台,能看到一堆类似这样的报错:

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

火山引擎 最新活动