浏览器缓存引起的bug总结
缓存原理
浏览器缓存分为强缓存和协商缓存
先检查是否过期,没有过期直接使用本地缓存。如果过期,查看是否使用协商缓存
协商缓存流程:
- 后端返回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
来辨别网站的缓存。