背景
今天在项目中遇到一个图片上传后裂图的错误
报错信息如下:
Refused to load the image
'unsafe:https://xxx.png' because it
violates the following Content Security Policy directive:"img-src
'self' blob: filesystem: data: xxx
分析
错误提示中,已经说是违反了Content Security Policy
指令,因为在Content Security Policy
中,没有配置对应的部分,那么会默认使用default-src
指令,而default-src
指令中没有设置我们发送请求url
设置,因此拒绝访问。
如果要设置允许请求数据的话,则需要设置Content-Security-Policy
的connect-src *
,意思是可以请求到任何的url
解决
那我的第一反应是在index.html
文件中加<meta>
标签,代码如下:
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content: https://xxx.com;media-src * blob: 'self' http://* 'unsafe-inline' 'unsafe-eval';style-src * 'self' 'unsafe-inline';img-src * 'self' data: content:;connect-src * blob:;">
注意:这里可以根据自己需要修改,例如img-src 允许 *
等多个类型的资源。 connect-src
允许*
blob:
等类型资源。注意*
并不包含blob:
类型,如果没有申明blob:
可能出错
很多同学在加了meta
标签后就将问题成功解决了,但是很不幸的是,我的代码加入之后还是仍然报错。
此时我展开了我打包后代码中的head
标签,并未发现刚刚被加入的meta
标签的身影,因此我考虑到可能是meta
标签加入失败,我就又在js
代码中手动加入了代码:
appendMeta = () =>{
// 在页面初始化时在head标签插入meta标签
const metaTag = document.getElementsByTagName('meta');
let isHasTag = true;
for(let i=0;i<metaTag.length;i++){ //避免重复插入meta标签
const httpEquiv = metaTag[i].httpEquiv;
if(httpEquiv == 'Content-Security-Policy'){
isHasTag = false;
}
}
if(isHasTag){
const headItem = document.head;
let oMeta = document.createElement('meta');
oMeta.setAttribute('http-equiv','Content-Security-Policy');
oMeta.content = 'default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content: https://ssl.gstatic.com;
media-src * blob: 'self' http://* 'unsafe-inline' 'unsafe-eval';
style-src * 'self' 'unsafe-inline';
img-src * 'self' data: content:;
connect-src * blob:;';
headItem.appendChild(oMeta)
}
}
此时再次查看head
标签,内部是成功插入了这段meta
的,但是图片依然还是裂的。
在多次搜寻结果无果后,我看见了这篇文章。这篇文章大概给我的指示是去修改nginx
配置添加 add_header Content-Security-Policy
,把需要访问的url
写进去 ,完成CSP
。
此时我找到后端同事,问题成功解决。
6