Content-Security-Policy下外部SVG<use>引用被拦截解决方案咨询
根因说明
你遇到的CSP拦截核心原因是外部SVG文件中的内联属性(比如<path>标签上的fill="#c20418")会被浏览器判定为内联样式,而SVG元素本身不支持nonce校验规则,主页面配置的style-src nonce对外部SVG文件的上下文不生效,因此会触发拦截。
可行解决方案(均无需配置unsafe-inline)
方案1:添加内联样式哈希到CSP规则(改动最小)
Chrome报错信息中已经给出了对应内联样式的哈希值,你只需要把该哈希值添加到style-src规则中即可:
style-src 'self' 'nonce-somenonce' 'sha256-Ptir/SKEXaGsdPsQ11Srj5YgYg3GDQ1ZV8flKlU21lI='
注意:如果后续修改了SVG文件中的内联样式属性,需要同步更新CSP中对应的哈希值。
方案2:移除SVG内联样式,统一通过外部CSS控制(可维护性最高)
- 删掉外部SVG文件中所有标签上的内联样式属性,比如
fill="#c20418"这类字段 - 在主页面带nonce属性的
<style nonce="xxx">标签中添加对应样式规则:
.atcls-1 { fill: #c20418; } /* 其他SVG图标需要的样式都可以在这里统一配置 */
该方案后续修改样式无需调整CSP规则,也不需要改动SVG文件,适配性最好。
方案3:将SVG sprite内联到HTML页面
把整个sprite.symbol.svg的内容直接复制到主页面<body>标签的最开头,给外层SVG添加hidden属性避免渲染:
<body> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" hidden> <symbol viewBox="0 0 40 40" id="arrow-right"> <path d="M29 20l-5-5v4H11v2h13v4l5-5z"/> </symbol> <symbol viewBox="0 0 22 22" id="icon-clock"> <path class="atcls-1" d="M17.727 9.777h-5.5v-5.5a1.222 ..."/> </symbol> </svg> <!-- 其他页面内容 --> </body>
再配合方案2的CSS规则控制样式,就无需加载外部SVG文件,也不会触发CSP拦截。
额外说明
你尝试配置style-src-elem无效的原因是该指令的校验上下文依然是主页面,对外部SVG文件中的内联样式不生效,且Firefox暂不支持该指令,不推荐使用。
内容的提问来源于stack exchange,提问作者Johannes Mols
相关产品推荐
相关产品推荐

