1. 程式人生 > 實用技巧 >瀏覽器快取引起的bug總結

瀏覽器快取引起的bug總結

快取原理

瀏覽器快取分為強快取和協商快取
先檢查是否過期,沒有過期直接使用本地快取。如果過期,檢視是否使用協商快取

協商快取流程:
  1. 後端返回headers:
ETag: W/"1e3-1754f0e63af"
Last-Modified: Thu, 22 Oct 2020 06:45:44 GMT
  1. 前端請求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,瀏覽器使用舊檔案。

快取問題

  1. 如果不設定快取時間(不設定cache-control或者expired),只設置協商快取,會有快取時間嗎?
    有,若只設置了協商快取,沒有設定強快取,則強快取時間大多預設是(date-last-modified)/10,而date只會去瀏覽器請求時更新,所以不會出現永久不過期情況。
  2. a網站與b網站不同域名,但是卻引用了相同地址的圖片test.jpg(都是跨域引用),瀏覽器先去訪問a網站,再去訪問b網站,那麼test.jpg會使用快取嗎?
    會,快取時瀏覽器行為,與域名無關。

快取引發的bug

  1. 修改了js,css,圖片等靜態檔案,但是卻沒有生效
    html禁止快取,並且在靜態檔案請求地址加查詢引數 src="test.js?1"
  2. 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

。那麼a網站使用了跨域,b網站再使用相同圖片。a網站請求圖片跨域access-control-allow-origin:a.com,但是b網站去跨域請求時,瀏覽器直接動用快取,此處直接跨域失敗。
因此網上有人提出方法:在b網站使用圖片時使用:img.src=url+'?' + Math.random(),但是無法快取,可以使用:img.src=url+'?'+location.origin來辨別網站的快取。