一次性解决It violates the following Content Security Policy directive: ‘iframe-src'..

5,143 阅读2分钟

背景

今天在项目中遇到一个图片上传后裂图的错误

image.png

报错信息如下:

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-Policyconnect-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