原文链接:https://segmentfault.com/a/1190000040831850
Cookie
Cookie是HTTP协议的一种无状态协议。当请求服务器时,HTTP请求都需要携带Cookie,用来验证用户身份。Cookie由服务端生成,存储在客户端,用来维持状态。
通常Cookie由以下值构成:
名称(name)值(value)域(Domain)值(value)路径(Path)失效时间(Expiers/Max-Age)大小(Size)是否为HTTP请求(HttpOnly)安全性(Secure)提示:域、路径、失效时间和安全性都是服务器给浏览器的指示,它们不会随着请求发送给服务器,发送给服务器的只有名称与值对。
Cookie有一些限制,它可以设置有过期时间,但是如果没有设置,则会和session一个级别,一旦关闭浏览器就会消失。
Cookie拥有以下优点:
- 可以控制过期时间,不会永久有效,有一定的安全保障。
- 可进行扩展,可跨域共享。
- 通过加密与安全传输技术(SSL),可以减少Cookie被破解的可能性。
- 有较高的兼容性。
缺点则如下:
- 有一定的数量与长度限制,每个Cookie长度不能超过4KB,否则超出部分会被截掉。
- 请求头上的数据容易被拦截攻击。
- 单个Cookie大小不超过4KB,很多浏览器都限制一个站点最多保存20个Cookie。
webStorage
H5可以在本地存储用户的浏览数据,以前用Cookie,但是webStorage更快速、安全。可以存储大量的数据,而不影响网站性能,以键/值对存在。
webStorage分为两种:sessionStorage和localStorage。
sessionStorage
sessionStorage将数据存储在session中,当浏览器关闭就会消失。它具有以下特色:
-大小5Mb-页面刷新数据不会消失,页面关闭就消失。-不可以跨页面(仅在当前页面使用)。-使用window.open打开页面和改变location.href方式可以获取到sessionStorage内部的数据。
主要被应用在下面这些场景中:
- 主要针对会话级的小数据的存储。
- 存储一些在当前页面刷新仍然需要存储,但是关闭后不需要留下的信息。
- 很适合单页应用的使用,可以用来存储登录态信息等。
localStorage
localStorage会把数据一直存在客户端本地。其API提供了如下的方法进行操作:
- setItem(key,value)——保存数据,以键值对的方式存储。
- getItem(key)——读取数据,传入键值(key),获得对应的值(value)。
- removeItem(key)——删除某个数据,删除键值对。
- clear()——删除所有数据。
- key(index)——获取某个索引的key。
下面是localStora的特性:
-大小5Mb。-可以跨页面。-永久存储,需要手动删除。-使用window.open打开页面和改变location.href方式可以获取到sessionStorage内部的数据。
它通常都被运用在下列场景中:
- 持久性的保存客户端数据,只能通过JavaScript删除或者用户清除浏览器缓存。
- 如果有一些稍大量的数据,例如编辑器的自动保存等。
- 多页面间访问共同数据。sessionStorage只能用于一个标签页,而localStorage可以在多个标签页之间共享。
浏览器缓存机制
浏览器的缓存机制是将已访问过的资源进行缓存,这样当客户端下次访问时,就能直接访问已经缓存的资源,从而减少服务器请求次数,让页面能够更快地加载。
而判断是否访问缓存则是依靠HTTP的各种Header,比如下面的这几种:
- Expires:响应头,表示该资源的过期时间。
- Cache-Control:请求头/响应头,是缓存控制字段。
- Etag(HTTP1.1):响应头,是资源标识,服务器存储。一旦资源被修改,Etag就会随之发生变化。
- lf-None-Match(HTTP1.1):请求头,一般服务器会将If-None-Match与被请求资源的最新ETag进行比对。
- Last-Modified(HTTP1.0):响应头,表示资源最后一次修改的时间。
- If-Modified-Since(HTTP1.0):请求头,资源最后一次修改时间(后面详情)。
这些Header共同组成了HTTP的请求和响应,也支撑着浏览器缓存,但是这种缓存方式是有缺陷的。
首先,如果资源更新的速度是秒以下单位,那么这个缓存是不能被使用的。因为它的时间单位最低是秒。
其次,如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间。哪怕文件可能没有变化,它也会自动更新,所以起不到缓存的作用。
强缓存
通常服务器会通知浏览器一个缓存时间,这个信息在Cache-Control和Expires中,浏览器通过这个判断是缓存否过期。如果时间未过期。则直接从缓存中取。这就是所谓的“强缓存”。
Expires
在HTTP1.0中。使用Expires字段来表示缓存的到期时间,即有效时间+当时服务器的时间。但是这种方式的缺陷是,用户只需要修改客户端本地时间,让客户端和服务器时间不一致时,浏览器就会判断缓存失效,然后重新请求资源。
Cache-control
Cache-Control是一个HTTP协议中关于缓存的响应头,它可以由以下值组成:
- max-age:用于设置缓存的最大周期。与Expires相反,它的时间是相对于请求的时间。
- s-maxage:和max-age相同,仅用于共享缓存,如CDN缓存。
- public:相应可以被任何对象缓存,即使是通常不可缓存的内容。
- private:缓存只能被单个用户缓存,不能作为共享缓存(即代理服务器不可缓存)。
- no-cache:可以缓存在客户端,但每次都必须去服务器检查新鲜度,来决定从服务器获取最新资源(200)还是读取缓存(304),即协商缓存。
- no-store:不允许在客户端存储,每次都要从服务器请求新的资源。
协商缓存
如果未命中强缓存,即强缓存失效(可能是Cache-Control设置了no-store或no-cache),则判断协商缓存。
Last-Modified&If-Modified-Since(HTTP1.0)
当第一次请求资源后,服务器会返回改资源最后一次修改的时间。之后再次请求时,服务器会对比If-Modified-Since和Last-Modified字段。如果两者相同,则表示资源未修改,返回304状态码。如果两者不同,则表示资源已经修改了,所以返回数据和200状态码(没有发送请求)。
但是如果服务器更新资源的时间单位为秒,而上面提到的方法是无法识别一秒内进行多次修改的情况的。同时如果资源更新的速度不到1ms,也是无法生成新的最后修改时间的。为了避免这种情况,在HTTP1.1中出现了一组新的字段:Etag和If-None-Match。
Etag&If-None-Match(HTTP1.1)
Etag是HTTP1.1的属性。它由服务器生成并返回给客户端,优先级高于Last-Modified。
在HTTP1.1中,当浏览器第一次发起HTTP请求时,服务器回返回一个Etag。浏览器第二次发起同一个请求时,客户端会发送一个If-None-Match,它的值就是Etag。服务器会比较浏览器发送过来的Etag和服务器的Etag,如果相同就将If-None-Match的值设置为false,并返回304,表示使用浏览器缓存。如果不同,服务器就将If-None-Match的值设置为true,返回200和新的数据。
网页加载速度的加快绝不仅仅是网速加快就能完成的,在我们流畅访问的背后,浏览器存储和缓存机制也功不可没,希望本文能够帮助大家增加对这个机制的了解。