瀏覽器快取引起的bug總結
阿新 • • 發佈:2020-10-22
快取原理
瀏覽器快取分為強快取和協商快取
先檢查是否過期,沒有過期直接使用本地快取。如果過期,檢視是否使用協商快取
協商快取流程:
- 後端返回headers:
ETag: W/"1e3-1754f0e63af"
Last-Modified: Thu, 22 Oct 2020 06:45:44 GMT
- 前端請求headers:
If-Modified-Since: Thu, 22 Oct 2020 06:26:38 GMT
If-None-Match: W/"1ef-1754efce5e8"
首先 If-Modified-Since與Last-Modified對比,這兒最後修改是在45分,快取的舊檔案是在26分,所以直接返回200及新檔案。
若 兩個時間相等,則對比etag與If-None-Match,若不同,則返回200,相同則返回304,瀏覽器使用舊檔案。
快取問題
- 如果不設定快取時間(不設定cache-control或者expired),只設置協商快取,會有快取時間嗎?
有,若只設置了協商快取,沒有設定強快取,則強快取時間大多預設是(date-last-modified)/10,而date只會去瀏覽器請求時更新,所以不會出現永久不過期情況。 - a網站與b網站不同域名,但是卻引用了相同地址的圖片test.jpg(都是跨域引用),瀏覽器先去訪問a網站,再去訪問b網站,那麼test.jpg會使用快取嗎?
會,快取時瀏覽器行為,與域名無關。
快取引發的bug
- 修改了js,css,圖片等靜態檔案,但是卻沒有生效
html禁止快取,並且在靜態檔案請求地址加查詢引數 src="test.js?1" - canvas使用跨域圖片生成新圖片失敗(非代理方式)
首先後端必須配合同意跨域。
前端img加上crossOrigin屬性
const img = new Image
img.setAttribute('crossOrigin', 'anonymous')
img.src='path-to-img'
img.onload=nextstep
如此,大概可以使用ctx.drawImage(img, x0,y0,x1,y1);canvas.toDataURL()了。
但是有一種例外,如果檔案伺服器,允許跨域,但access-control-allow-origin值不是*
,並且沒有設定cache-control:no-cache
access-control-allow-origin:a.com
,但是b網站去跨域請求時,瀏覽器直接動用快取,此處直接跨域失敗。因此網上有人提出方法:在b網站使用圖片時使用:
img.src=url+'?' + Math.random()
,但是無法快取,可以使用:img.src=url+'?'+location.origin
來辨別網站的快取。