浏览器缓存
什么是浏览器缓存
浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。
浏览器缓存的优点
- 减少了冗余的数据传输
- 减少了服务器压力,提升了网站性能
- 加快了页面加载的速度
协商缓存与强缓存
强缓存:如果缓存资源有效,就不会向服务器发送请求,直接从缓存中读取资源,返回200状态码。
强缓存可以通过两种方式来设置:分别是htpp头信息中的Expires属性和Cache-Control属性。
- 服务器通过在响应头中添加 Expires 属性,来指定资源的过期时间。在过期时间以内,该资源可以被缓存使用,不必再向服务器发送请求。这个时间是一个绝对时间,它是服务器时间。使用服务器时间有这个坏处:客户端与服务器的时间可能会不一样并且用户可以对客户端时间进行修改,影响缓存命中的结果。
- Cache-Control是HTTP1.1中提出的,提供了对资源更精确的控制。一般使用max-age设置缓存最大的有效期。
Cache-Control的优先级比Expires高。
协商缓存:如果命中了强制缓存,那我们就不需要再向服务器发起请求,直接使用缓存资源。若没有命中则使用协商缓存。
命中协商缓存的条件有两个:
- max-age过期
- 使用no-cache
协商缓存策略:先向服务器发送一个请求,如果资源没有发生修改,则返回一个304状态,让浏览器使用本地缓存,如果资源发生了修改,则返回修改后的资源。
协商缓存通过两种方式设置,分别是http头信息中的Etag和Last-Modified:
- 服务器通过响应头来添加Last-Modified表示资源最后一次修改的时间。当浏览器下一次发起请求时,会在请求头中加一个if-Modified-Since属性,表示上次返回资源时的Last-Modified属性。当服务器收到请求后,通过if-Modified-Since属性与资源最后一次修改时间进行对比,以此来判断是否做了修改。
- 因为使用Last-Modified可能会不准确,http提供了Etag属性。当服务器返回资源时,会在头信息中添加Etag属性,这个属性是资源生成的唯一标识符,当资源发生改变时,Etag也会发生变化。在下一次资源请求时,浏览器会在请求头中添加一个 If-None-Match 属性,这个属性的值就是上次返回的资源的 Etag 的值。服务接收到请求后会根据这个值来和资源当前的 Etag 的值来进行比较,以此来判断资源是否发生改变。
总结: 强缓存的优先级高于协商缓存。强缓存策略和协商缓存策略在缓存命中时都会直接使用本地的缓存副本,区别只在于协商缓存会向服务器发送一次请求,判断缓存是否命中。它们缓存不命中时,都会向服务器发送请求来获取资源。在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。
对浏览器的缓存机制的理解
浏览器缓存全过程:
- 浏览器第一次加载资源时,服务器返回200,浏览器从服务器下载该资源文件,并缓存资源文件与response header,以供下次加载时对比使用
- 下次加载资源时,由于强制缓存优先级较高,先比较当前时间与上次返回200时的时间差,如果没有超过cache-control(控制HTTP缓存)设置的max-age,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用Expires头判断是否过期
- 如果资源已过期,则表明强缓存没有被命中,则开始协商缓存,向服务器发送带有if-None-Match(Etag)和if-Modified-Since(Last-Modified)的请求
- 服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200
- 如果服务器收到的请求没有Etag值,则将if-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200
很多网站的资源后面都加了版本号,这么做是因为:每次升级了JS或CSS文件后,为了防止浏览器进行缓存,强制改变版本号,客户端浏览器就会重新下载新的JS或CSS文件,以保证用户能够及时获得网站的最新更新。
点击刷新按钮或者按 F5、按 Ctrl+F5 (强制刷新)、地址栏回车有什么区别?
- 点击刷新按钮或者按F5:浏览器直接对本地缓存的文件过期,但是会带上If-Modifed-Since,If-None-Match,这就意味着服务,返回结果可能是 304,也有可能是 200。
- 按Ctrl+F5 (强制刷新):浏览器不仅对本地缓存文件过期,还不会带上If-Modifed-Since,If-None-Match,相当于之前没有请求过,返回200状态。
- 地址栏回车:浏览器发起请求,按正常的强缓存 -> 协商缓存 -> 请求资源的过程执行。
浏览器本地存储
浏览器本地存储方式及使用场景
(1) Cookie 在使用HTTP协议本身不对请求和响应之间的通信状态进行保存,所以引用了Cookie,Cookie的本质是一个文本,可以用来判断网络中两个请求是否由同一个用户发起的。
Cookie的组成
- NAME=[VALUE]
Cookie的值,NAME是唯一标识Cookie的名称,不区分大小写;VALUE是存储在Cookie里的字符串值,该值必须通过URL编码 - Domain=[域名]
Cookie有效的域,发送到这个与所有的请求都会包含对应的Cookie - Path=[PATH]
- Expires=[DATE]
Cookie的有效期。浏览器结束后会删除所有Cookie - Secure
设置仅在使用HTTPS进行通信时才发送Cookie - HttpOnly
设置只在服务器上读取,不能再通过JS读取Cookie
Cookie的特性
- Cookie一旦创建成功,名称就无法改变
- Cookie在请求一个新的页面时,都会被发送过去
- Cookie是无法跨域的,这也保证了隐私性和安全性,无法获取其他网站的Cookie。如果想要不同域之间共享Cookie,必须使用Nginx反向代理或向其他网站写Cooike
- Cookie的体积小,一般不超过4k
- Cookie的个数有限,如果超过Cookie个数的限制,则会删除之前设置的Cookie
Cookie的使用场景:
- 统计页面的点击次数
- 与session结合使用,将sessionId存储到Cookie中,每次发送请求都携带这个sessionId,这样服务器段就知道是谁发送的请求了。
(2) LocalStorage 有时我们储存的信息比较多,Cookie就存储不下了,这时候就需要LocalStorage。
LocalStorage的优点:
- 相比Cookie可以存储更多的信息,大小一般为5MB
- LocalStorage是持久存储的,除非主动清理,不然会永久存在
- 仅储存在本地,不会像Cookie那样每次发起请求都会被携带
LocalStorage的缺点:
- 存在浏览器兼容问题
- 如果浏览器设置为隐私模式,则无法读取到LocalStorage
- 受同源策略的限制,即端口、协议、主机地址有任何一个不相同都不会访问
LocalStorage常用的API:
LocalStorage.setItem("key", "value")
LocalStorage.getItem("key")
LocalStorage.removeItem("key")
LocalStorage.clear()
LocalStorage.key(index)
LocalStorage的适用场景:
- 网站有换主题之类的功能
- 在网站中用户的浏览信息也会保存到LocalStorage中,还有网站中不常变动的个人信息也保存在LocalStorage中。
(3) SessionStorage SessionStorage用于临时保存同一个标签页中的数据,刷新页面不会删除SessionStorage,关闭标签页才会删除SessionStorage。
SessionStorage和LocalStorage的对比:
- SessionStorage和LocalStorage都存储在本地
- SessionStorage也有同源策略的限制,SessionStorage只有在同一浏览器的同一窗口下才能共享
- SessionStorage和LocalStorage都不能被爬虫获取
SessionStorage常用的API:
SessionStorage.setItem("key" ,"value")
SessionStorage.getItem("key")
SessionStorage.removeItem("key")
SessionStorage.clear()
SessionStorage.key(index)
SessionStorage的适用场景: 由于SessionStorage具有时效性,可以用来存储一些网站的游客登录信息,还有临时的浏览记录的信息,当网站关闭之后,这些信息也就随之消除了。
Cookie、LocalStorage、SessionStorage区别
- Cookie:Cookie是服务器端用于记录用户状态的一种方式,由服务器设置,在客户端存储,然后每次发起同源请求后,发送给服务器端,Cookie最多能存储4k,生命周期由expires指定,Cookie只能被同源的页面访问共享。
- LocalStorage:是浏览器本地存储的方法,除非手动删除,不然会被永久保存在本地,可以用来存储主题颜色、用户一些补偿修改的信息等,只能被同源的页面访问。
- SessionStorage:是浏览器本地存储方法,刷新不会删除存储,在关闭页面时会删除存储,SessionStorage只能被同一个窗口的同源页面访问。
:IndexedDB
当本地存储大量数据时,就可以使用:IndexedDB。:IndexedDB是浏览器提供的一种本地的数据库存储机制,他不是关系型数据库,它内部采用对象仓库的形式存储数据。
- 一个域名下可以包含多个数据库
- 一个数据库包括多个对象仓库
- 每个对象仓库中包含多条数据记录
IndexedDB的特点
- 键值对存储:所有类型的数据都可以直接存入,包括JS对象。对象仓库中,数据以“键值对”的形式保存,每条数据记录都有对应的主键,主键都是独一无二的,不能有重复。
- 异步:IndexedDB操作时不会锁死浏览器,用户依然可以进行其他操作。LocalStorage的操作是同步的。异步的设计是为了防止大量数据的读写,拖慢网页的表现。
- 支持事务:如果在操作时有一步失败,那么整个事务就取消,数据库就回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
- 同源限制:每个数据库对应创建它的域名,网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
- 存储空间大
- 支持二进制存储
|