HTTPS中Content-Security-Policy(CSP)导致的资源无法加载的问题

解决HTTPS中Content-Security-Policy(CSP)默认限制导致的前端资源无法加载的问题

# 背景

前端同事有个复杂的前端项目,基于开源项目二次开发,使用了three.js等工具在浏览器中进行复杂的三维图像绘制,以及拥有视频播放时在上方同步绘制信息框等功能。该项目之前在测试环境时运行良好,但部署到生产环境后出现部分图像或字体无法绘制的问题,console里不断报错。前端同事表示一个人解决不了,于是用奶茶作为报酬拉上我一起研究。

# 思路

首先确立问题背景:

  1. 本地开发环境及测试环境正常打开,生产环境部分资源无法绘制。编译部署的代码几乎完全相同,问题应该不是出在代码而是环境差异
  2. 仔细检查了两边的nginx,除了测试为http及生产为https外,两者配置完全相同
  3. 怀疑是https证书的配置问题。但同样的配置相对于其他vue2及vue3的普通前端项目没有任何问题。
  4. 最后仔细查看console报错,报错内容大多数是fail to fetch 'data:xxxxxxxx', 由于 Content-Security-Policy 浏览器阻止了相关资源加载

于是我们直接开始问AI大模型,Content-Security-Policy阻止策略是什么?最后了解到CSP基本的原理如下:Content Security Policy (CSP) 是一种重要的浏览器安全机制,旨在帮助防止跨站脚本 (XSS) 和其他代码注入攻击。简单的来说,它通过一系列限制,只允许从指定的域名加载指定的资源。一般来说是同个网站的普通的html、css等都在他的允许范围内,超过这个范围的就禁止浏览器读取。

那我们同一个域名的其他前端项目都好好的,这个三维绘图项目怎么就不行了被禁止加载了?于是让前端同事去看了代码,里面用了data:xxxx的方式去加载字体。这是由于有多个线程绘制不同的三维图像,为了效率使用了多个worker线程。并且在worker线程里用data:请求字体资源才能正确加载资源,这个不好改。于是前端同事让我看看能不能在不改代码的情况下,让浏览器放开CSP的限制。

于是我查了一些资料,发现可以在NGINX中通过配置返回值的header,在返回值中加入‘Content-Secutiry-Policy’ 字段及控制字段,控制浏览器的行为。参考:https://wangshuashua.com/nginx-configcspcontent-security-policy/

最后我们决定增加如下配置。

1
2
# 解释:允许data方式加载,允许inline方式的内联函数
add_header Content-Secutiry-Policy "default-src 'self'; connect-src * data:; style-src 'self' 'unsafe-inline';"

完美解决问题,前端数据在放开CSP限制后正确加载了

使用 Hugo 构建
主题 StackJimmy 设计