动态

详情 返回 返回

在Chrome瀏覽器中,即使<img crossOrigin=anonymous>也會被同源策略攔截 - 动态 详情

在一次開發中,遇到了生成海報的需求:在圖片相冊界面用户選擇若干張圖片,在海報編輯界面用户通過拖動這些圖片生成一張海報,供用户下載。

在圖片相冊界面,圖片均展示正常且無報錯發生。當用户選擇若干張圖片之後,進入海報編輯界面前,添加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屬性,使緩存能匹配期望的響應。

user avatar toopoo 头像 dingtongya 头像 Leesz 头像 zaotalk 头像 jingdongkeji 头像 kobe_fans_zxc 头像 longlong688 头像 febobo 头像 ccVue 头像 nqbefgvs 头像 kongsq 头像 xw-01 头像
点赞 84 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.