背景
本地完全OK,所有图片(svg,png等)都可以正常加载,环境上除了阿里G6的网格加载不出来其他正常。但是突然有一天,环境上除了阿里G6的网格,还有其他表示类型的图片(png)也都加载不出来。
分析
F12可以看到控制台报了XXXContent Security PolicyXXX之类的错误(公司电脑无法截图),所以怀疑是CSP相关的原因,后来看了下代码,由于安全原因,后台给http都加了头信息Content-Security-Policy。
vue-cli3打包的时候,对图片打包进行了优化,默认小于10KB的图片(比如png,注意svg不会)转为base64。
base64就是一串字符串码来表示的图片,在加载页面或者js的时候就一并加载过来,减少图片引用时单独的一次http请求,从而优化http请求,保证页面加速渲染。
如果Content-Security-Policy: default-src 'self',就导致了环境上的图片加载失败。
CSP策略
本质上是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。可以预防XSS攻击。
CSP的开启方法:
a.通过 HTTP 头信息的Content-Security-Policy的字段(后端)
b.通过网页的标签(前端)
如果Content-Security-Policy: default-src 'self',会限制所有的外部资源(img,font,script,style等等),都只能从当前域名加载
解决
a.CSP策略放开img
b.图片不做base64转换
chainWebpack: config => { config.module .rule('images') .use('url-loader') .loader('url-loader') .tap(options => Object.assign(options, { limit: -1 })) }
拓展:url-loader 和 file-loader的区别
file-loader 返回的是图片的url
url-loader 可以通过limit属性对图片分情况处理,当图片小于limit(单位:byte)大小时转base64,大于limit时调用file-loader对图片进行处理。
参考
Content Security Policy 入门教程
webpack的url-loader和file-loader的区别