zoukankan      html  css  js  c++  java
  • 浏览器缓存引起的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来辨别网站的缓存。

  • 相关阅读:
    JavaScript-循环
    JavaScript-条件判断
    JavaScript-对象
    Vue快速入门
    Typora中的MarkDown语法
    (已解决)ERROR: In file './docker-compose.yml', service 'networks' must be a mapping not an array
    mac常用快捷键
    Python数据分析
    Python列表和元组
    Selenium工具爬取商品
  • 原文地址:https://www.cnblogs.com/gsgs/p/13858847.html
Copyright © 2011-2022 走看看