关于chrome:在Chrome浏览器中即使img-crossOriginanonymous也会被同源策略拦截

32次阅读

共计 1646 个字符,预计需要花费 5 分钟才能阅读完成。

在一次开发中,遇到了生成海报的需要:在图片相册界面用户抉择若干张图片,在海报编辑界面用户通过拖动这些图片生成一张海报,供用户下载。

在图片相册界面,图片均展现失常且无报错产生。当用户抉择若干张图片之后,进入海报编辑界背后,增加 cors 属性 <img crossOrigin=anonymous> 从新加载这些图片,以便 canvas 解决这些图片数据(图片增加 cors 属性起因)。神奇的是:所有的图片均无奈显示,报错 `……has been blocked by CORS policy: No
Access-Control-Allow-Origin header is present on the
requested resource.`,原来被浏览器的同源策略拦挡了。

这些图片寄存在 Amazon S3,都配置了容许跨域拜访。增加了 cors 参数的 img 不应该被同源策略拦挡,而无奈显示。

形象问题,并探索

增加图片的办法:

const appendImage = (imageUrl, crossOrigin = 'anonymous') => {const image = document.createElement('img')

    if (crossOrigin) image.crossOrigin = crossOrigin
    image.src = imageUrl

    document.body.append(image)
}

当在 Chrome 浏览器中增加全新的图片时,显示失常:

清空浏览器缓存之后,当在浏览器中加载须要 cors 属性的图片时,显示失常:

清空浏览器缓存之后,当在浏览器中增加该图片时,显示失常;增加 cors 属性而后加载该图片时,无奈显示:

通过 Response Headers 能够看到:因为没有响应 Access-Control-Allow-Origin 字段,被浏览器的 CORS 策略拦挡了。

初步论断:通过以上三个景象能够得悉,开发需要时的异常现象应该与 Chrome 浏览器的缓存无关。

起因

通过查问相干文档,发现早在 2014 年就有人给 chromium 提出 issue:图片资源(url)会缓存在浏览器中,下次访问雷同的图片资源(url)时,返回被缓存资源的 response。

联合下面的开发需要,能够得出起因:

  1. 图片相册界面中的图片,均以未增加 cors 属性的形式申请,response 返回无跨域头的数据,加载之后便被浏览器缓存;
  2. 海报编辑界面中的图片,均以增加 cors 属性的形式申请,浏览器返回已有的缓存数据;
  3. 因为缓存数据无跨域头,导致以增加 cors 属性的形式申请的图片资源,被浏览器的同源策略屏蔽掉。

然而 Chromium 的开发团队将该问题标记为WontFix(Closed),可能是因为比拟合乎 Chromium 引擎的预期行为。

解决方案

在得悉起因之后,便着手解决方案:为图片 url 的 search 局部增加一个字段,用来辨别无 cors 属性的申请。

const appendImage = (imageUrl, crossOrigin = 'anonymous') => {const image = document.createElement('img')
    let src = imageUrl

    if (crossOrigin) {src = new URL(src)
        src.searchParams.append(`cors-type`, crossOrigin)
        src = src.toString()

        image.crossOrigin = crossOrigin
    }

    image.src = src

    document.body.append(image)
}

批改 appendImage 函数之后,再次申请图片,有无 cors 属性的图片均展现:

总结

Chrome 浏览器的图片缓存,只按 url 来辨别,因而有无 cors 属性的图片在申请时是无差别的。若缓存数据无响应 Access-Control-Allow-Origin 字段,而图片资源须要该字段时就会产生问题。

在 url-search 里增加字段,用以辨别有无 cors 属性,使缓存能匹配冀望的响应。

正文完
 0