緩存原理
瀏覽器緩存分為強緩存和協商緩存
先檢查是否過期,沒有過期直接使用本地緩存。如果過期,查看是否使用協商緩存
協商緩存流程:
- 后端返回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
。那么a網站使用了跨域,b網站再使用相同圖片。a網站請求圖片跨域access-control-allow-origin:a.com
,但是b網站去跨域請求時,瀏覽器直接動用緩存,此處直接跨域失敗。
因此網上有人提出方法:在b網站使用圖片時使用:img.src=url+'?' + Math.random()
,但是無法緩存,可以使用:img.src=url+'?'+location.origin
來辨別網站的緩存。