瀏覽器端CORS策略 + 緩存策略 導致的 跨域策略失效 問題
問題現象
DataV的屏幕上發現了這麼個詭異的現象:
在開發的屏幕中,用xhr加載圖片供canvas渲染,時好時壞,報錯的異常是:跨域失敗,查看network的請求,在失敗的時候,圖片返回的header裏確實缺失了cors的幾個關鍵信息。
而且開發的同學經常是好的,到了用戶手裏就不行。
服務器端的oss策略仔細檢查了,沒有問題, 而且屏幕上有時候是好的,說明服務至少正常過。oss的接口冪等基本上不用懷疑,所以把疑問再次轉回到客戶端。
在一次本地重現之後,在network裏過濾出錯圖片地址,結果發現除了 xhr的請求,還有一個標簽發起的請求, 把調試器的緩存關閉之後,刷新屏幕頁麵,重現了。
故障原因
上述頁麵有兩個請求指向同一個 圖片地址, 當img標簽先行的時候,
<img src="pic.png"/>
瀏覽器返回了圖片,但是由於img標簽發起請求的時候並不會帶上 Origin頭,所以Aliyun OSS在返回的response header 裏並沒有帶上 cors需要的 Access-Control-Allow-Origin
等信息,因為 標簽並不受同源策略限製。 於是瀏覽器 cache了這個圖片請求,當然也包括header信息。
當 xhr再次發起對這個圖片的請求時,命中了瀏覽器緩存,這時候問題就出現了,header裏沒有告訴xhr可以信任當前域,所以瀏覽器拒絕了這個請求。
解決辦法
最簡單的辦法,把兩個調用地址區分開,xhr可以加個 ?xhr
所以這種異常,不是OSS的鍋
瀏覽器需要改進麼?
目前瀏覽器緩存策略隻是根據資源地址來cache,並沒有區分調用形式,以及調用時header的差異。
作為資源cache,也合情合理。
不過曆史原因, 圖片資源、script標簽 等,瀏覽器一直沒有對這些請求開啟同源策略限製,當然也無法開啟(一旦大量的站點要掛)。
有沒有必要開啟? 能不能開啟? 這是另外的問題,但是Origin的頭可以先帶上。
最後更新:2017-10-23 15:34:21