缓存

1. 缓存的分类

缓存的分类
本文中讨论的是浏览器(客户端)缓存

2. 缓存机制

!!一定要弄懂下面这张图的机制和过程
缓存机制

概述

基本原理:

  1. 浏览器在加载资源的时候,根据请求头的ExpiresCache-Control判断是否命中强缓存,如果是,就直接从缓存读取资源,不会给服务器发请求。
  2. 如果没有命中强缓存,浏览器会发送一个请求到服务器,浏览器通过Last-ModifiedETag标识验证资源是否命中协商缓存,如果是,则返回304和Not Modified,然后浏览器从缓存读取数据,如果不是则返回200和请求结果。

相同点:
如果命中,都是从客户端缓存中读取资源,而不是从服务器加载资源
不同点:
强缓存不发请求到服务器,协商缓存要发请求到服务器

3. 强缓存

强缓存可以通过两种HTTP header实现:ExpiresCache-Control

  1. Expires :HTTP 1.0提出的一个表示资源过期时间的头部,它描述的是一个绝对的时间,由服务器返回。Expires受限于本地时间,如果修改了本地时间,可能会导致缓存失效。

Expires: Wed, 22 Oct 2018 08:41:00 GMT表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。

  1. Cache-Control : 出现于HTTP 1.1,优先级高于Expires,表示的是相对时间。

当Cache-Control:max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。

Cache-Control的指令:
在这里插入图片描述

  • no-cache:标识为no-cache的响应实际上是可以存储在本地缓存区的,只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用
  • no-store:真正的不缓存数据到本地
  • public: 可以被所有用户缓存,包括终端和CDN等中间代理服务器,可以被任何的中间节点缓存
  • private: 所有内容只有客户端可以缓存,Cache-Control的默认取值
4. 协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:

  • 协商缓存生效,返回304和Not Modified
  • 协商缓存失效,返回200和请求结果

协商缓存利用的是【Last-Modified, If-Modified-Since】和【ETag,If-None-Match】这两对Header来管理。

  1. Last-Modified, If-Modified-Since】: 浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;浏览器下一次请求这个资源,检测到有Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器收到请求后,会把这个时间和请求资源的最后修改时间对比,成功则304和空的响应体,失败则返回新的资源文件和200。

但是这样的情况下还是有一些弊端:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变了修改时间),这时我们并不希望客户端认为这个文件被修改而重新GET;
  • 某些文件修改是非常频繁的,比如在秒以下的时间内进行修改(例如1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断;
  • 某些服务器不能精确的得到文件的最后修改时间。

基于以上这些弊端,就在HTTP 1.1 出现了ETag。
2. 【ETag,If-None-Match】:服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化(跟时间没关系),Etag就会重新生成,Etag能保证每个资源是唯一的。浏览器在下一次加载资源向服务器发送请求时,会将服务器上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致。如下图:
协商缓存Etag
两者之间的对比:
(1). 首先在精确度上,Etag要优于Last-Modified。

Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。

(2). 第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
(3). 在优先级上,服务器校验优先考虑Etag。

5.Memory Cache和Disk Cache

在这里插入图片描述
Memory Cache:
内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
Disk Cache:
就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。不会随着页面的关闭而释放。

数据存储:cookie、Storage、indexedDB

简单对比

  1. cookie : 4K,可以手动设置失效期
  2. localStorage : 5M,除非手动清除,否则一直存在
  3. sessionStorage : 5M,不可以跨标签访问,页面关闭就清理
  4. indexedDB : 浏览器端数据库,无限容量,除非手动清除,否则一直存在
cookie和session
1. cookie

Cookie通过在客户端记录信息确定用户身份
Session通过在服务器端记录信息确定用户身份

cookie机制:
一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话。
HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
cookie其实是一小段的文本信息。(1). 客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个cookie;(2). 客户端浏览器会把cookie保存起来;(3). 当浏览器再请求该网址时,浏览器把请求的网址和cookie一起发送给服务器; (4). 服务器检查cookie,辨认用户状态。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围

2. session

session机制:
session也是一种记录用户状态的机制,不同的是cookie保存在客户端浏览器中,session保存在服务器上。
客户端访问服务器的时候,服务器会把客户端的信息以某种形式记录在服务器上,这就是session。当浏览器再访问时,服务器只需要从session中查找该客户的状态。

如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

当程序需要为某个客户端的请求创建一个session时:

  1. 服务器首先检查这个客户端的请求里是否已经包含了一个session标识-------称为session ID
  2. 如果已经包含就说明之前已经为这个客户端创建过session,服务器就按照这个session ID 把这个session找出来使用(如果找不到还是会新建一个)
  3. 如果客户端请求中不包含session ID,服务器就为这个客户端建立一个session,并且生成一个与此session相关联的session ID(应该是一个既不会重复,又不容易被找到规律来模仿的字符串),这个session ID将在本次响应中被返回给客户端保存。

可以用document.cookie获取cookie,得到一个字符串,形式如key1=value1; key2=value2,需要用正则匹配需要的值。
cookie可以设置路径path,所以它比StorageindexedDB多了一层访问限制
cookie可以通过设置domain属性值,在不同的二级域名下共享cookie,比如http://image.baidu.com的cookiehttp://map.baidu.com是可以访问的,前提是Cookie的domain设置为.http://baidu.com,而Storage不可以。
缺点:
在请求头中带数据,大小在4K之内,主domain污染
常用的配置属性:
Expires:cookie最长的有效期
Max-Age:在cookie失效之前经过的秒数。(当Expires和Max-Age同时存在时,文档中给出的是以Max-Age为准,但是作者在Chrome中实验的结果是取二者中最长有效期的值)
Domain:指定cookie可以送达的主机名
Path:指定一个URL路径,这个路径必须出现在要请求的资源中才可以发送cookie首部
Secure::一个带有安全属性的cookie只有在请求使用SSL和HTTPS协议的时候才会被发送到服务器
HttpOnly:设置了 HttpOnly 属性的cookie不能使用JavaScript经由document.cookie属性、XMLHttpRequestRequest APIs 进行访问,以防范跨站脚本攻击(XSS


Storage:localStorage、sessionStorage

大小:官方建议是5M存储空间
类型:只能操作字符串,所以在存储之前要使用JSON.stringify()方法先转换成字符串,取值时再用JSON.parse()方法再转换一次
存储的内容:数组、图片、json、样式、脚本等能序列化成字符串的所有内容
注意:数据是明文存储,无隐私性,所以绝对不能用来存储重要信息
区别:localStorage将数据存储在本地,理论上来说除非手动清除,否则一直存在;sessionStorage将数据临时存储在session中,浏览器关闭,数据就消失

不同浏览器无法共享localStorage和sessionStorage中的信息,同一浏览器的相同域名和端口的不同页面可以共享localStorage,但是无法共享sessionStorage的信息

基本操作API

保存数据
localStorage.setItem( key, value );
sessionStorage.setItem( key, value );
读取数据
localStorage.getItem( key, value );
sessionStorage.getItem( key, value );
删除单个数据
localStorage.removeItem( key, value );
sessionStorage.removeItem( key, value );
删除全部数据
localStorage.clear( );
sessionStorage.clear( );
获取索引的key
localStorage.key( index );
sessionStorage.key( index );

监听storage事件

可以通过监听window对象的storage事件并指定其处理函数,当页面中对localStorage或sessionStorage进行修改时,则会触发对应的处理函数

window.addEventListener('storage',function(e){
  	console.log('key='+e.key+',oldValue='+e.oldValue+',newValue='+e.newValue);
})

触发事件的事件对象(e)有几个属性:
key:键值
oldValue:被修改之前的值
newValue:被修改之后的值
url:页面URL
storageArea : 被修改的 storage 对象。


indexedDB

要想系统学习这方面的知识,可以去MDN文档看API。还有http://www.zhangxinxu.com/wordpress/2017/07/html5-indexeddb-js-example/
https://github.com/amandakelake/blog/issues/13

对比
  • 如果是浏览器主窗体线程开发,同时存储数据结构简单,localStorage比较好;
  • 如果数据结构比较复杂,同时对浏览器兼容性没什么要求,可以考虑使用indexedDB
  • 如果是在Service Workers中开发应用,只能使用indexedDB数据存储。
  • indexedDB数据库的使用目前可以直接在http协议下使用,这个和cacheStorage缓存存储必须使用https协议不一样

cacheStorage缓存页面,indexedDB数据库缓存数据,两者一结合而就可以实现百分百的离线开发

localStorage,sessionStorage和cookie的区别

共同点:都是保存在浏览器端、且同源的(同源指同协议、同域名、同端口)
区别

  • cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStoragelocalStorage不会自动把数据发送给服务器,仅在本地保存。
  • cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
  • 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识sessionStoragelocalStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
  • 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  • 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的

https://github.com/amandakelake/blog/issues/43
https://www.jianshu.com/p/54cc04190252

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值