项目中遇到一个问题,同一个图片在 dom 节点中使用了 'img' 标签来加载,同时因为项目使用了 ThreeJS 3D 渲染引擎,在加载纹理时使用了 TextureLoader 来加载了同一张图片,而因为图片是在阿里云服务器上的,因此最后报出了以下错误,意思是在访问图片时出现了跨域问题: html
图片是来自于阿里云服务器的,和本地 localhost 必然存在跨域问题。经过 dom 节点的 'img' 标签来直接访问是没有问题,由于浏览器自己不会有跨域问题。问题出在经过 TextureLoader 来加载图片时出现了跨域问题。查看了 TextureLoader 的源码,发现其进一步使用了 ImageLoader 来加载图片,加载图片的代码大体以下:canvas
crossOrigin: 'anonymous',
......
var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
......
if ( url.substr( 0, 5 ) !== 'data:' ) {
if ( this.crossOrigin !== undefined )
image.crossOrigin = this.crossOrigin;
}
......
image.src = url;
复制代码
这段代码所描述的大体思路是:跨域
因此,问题的关键在于,同一张图片,先用 'img' 标签去加载了,而后再在 JS 代码中,建立一个 'img' 而且设置了 crossOrigin 的跨域属性为 'anonymous',那么在 JS 中建立的 'img' 就会出现访问图片而产生跨域的问题。浏览器
关于 crossOrigin,咱们看看 MDN 的解释。缓存
这段话,用我本身的理解来解释一下:bash
经过前面 2 点的梳理,咱们得出以下结论:服务器
前面经过勾选 disable cache 来避免浏览器使用缓存图片而解决了问题,但实际用户不会这样使用啊。根据前面的梳理,'img' 不跨域请求,而 JS 中的 'img' 跨域请求,因此不能访问缓存,那么是否是能够将 JS 中的 'img' 也设置成不跨域呢,因而将 JS 中的 'img' 的 crossorigin 设置为 undefine,结果图片是能够加载了,但又获得以下错误。网络
这段错误的意思是,这一个来自于CORS 的图片,是不能够再次被复用到 canvas 上去的。这就验证了关于 crossorigin 中的第 1 点。dom
既然 'img' 和 JS 中的 'img' 都不加 crossorigin不能解决 canvas 重用的问题,那么在两边同时都加上 crossorigin 呢?果真,在 'img' 中和 JS 中的 'img' 都加上 crossorigin = "anonymous",图片能够正常加了,同时也能够被复用到 'canvas' 上去了。this
另外,须要注意的 2 个小问题是:
Access-Control-Allow-Origin: *
前面说了一框,只是想把这个过程完整的记录下来。整个问题的总结是:
最后,感谢你能读到并读完此文章,若是分析的过程当中存在错误或者疑问都欢迎留言讨论。若是个人分享可以帮助到你,还请记得帮忙点个赞吧,谢谢。