項目中遇到一個問題,同一個圖片在 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: *
前面說了一框,只是想把這個過程完整的記錄下來。整個問題的總結是:
最後,感謝你能讀到並讀完此文章,若是分析的過程當中存在錯誤或者疑問都歡迎留言討論。若是個人分享可以幫助到你,還請記得幫忙點個贊吧,謝謝。