缓存那些事儿

一、cookie和session
cookie和session都是为了弥补http协议的无状态特性,对服务端来说无法知道两次http请求是否来自同一个用户,利用cookie和session让用户只登录一次,服务端就知道某个请求是否需要重新登录。
cookie保存在客户端,session保存在服务器,session依赖于cookie。
cookie是一些用户信息,不是缓存。

那什么是缓存呢?缓存是浏览网页产生的临时文件,比如图片,css,js。
web缓存有很多种,比如浏览器缓存、CDN缓存、数据库缓存、代理服务器缓存。
常用的客户端缓存指浏览器缓存,服务端缓存指CDN缓存
下面将着重介绍浏览器缓存,简单介绍CDN缓存,以及缓存的好处和弊端。

二、浏览器缓存
浏览器缓存是将文件保存在客户端,在同一个会话过程中会检查缓存的副本是否足够新,后退网页时,访问过的资源可以从浏览器缓存中拿出使用。
页面的缓存状态由响应头header决定,下面将介绍4个header参数,强缓存中的Expires和cache-control,协商缓存中的Last-Modified/If-Modified-Since和Etag/If-None-Match。

1、强缓存
直接从本地缓存中取资源,不会和服务器通信,返回的http状态码是200(from cache),由headers中的expires和cache-control决定。
A、expires
缓存过期时间是一个绝对时间,由服务器返回,用GMT格式的字符串表示。expires是Web服务器响应消息头字段,在响应http请求时,告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
expires = max-age + 请求时间,需要结合Last-modified使用。
读取缓存数据条件:缓存过期时间(服务器的) < 当前时间(客户端的)
B、cache-control
是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,所以cache-control
比expires的缓存管理更有效,更安全。
读取缓存数据条件:max-age + 上次缓存时间(客户端的) < 当前时间(客户端的)

max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。

s-maxage(单位为s)同max-age,只用于共享缓存(比如CDN缓存)。
比如,当s-maxage=60时,在这60秒中,即使更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用于普通缓存,而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖掉max-age和Expires header。

public指定响应会被缓存,并且在多用户间共享。如果没有指定public还是private,则默认为public。

private响应只作为私有的缓存,不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。

no-cache指定不缓存响应,表明不缓存资源。
设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。只设置no-cache防止缓存不够保险,再加上private指令,将过期时间设为过去的时间。

no-store绝对禁止缓存,每次请求资源都要从服务器重新获取。

以上两个header可以只启用一个,也可以同时启用,当response header中,Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires。

2、协商缓存
通过服务器来告知是否能用本地缓存。先和服务器通信,如果返回304,就从本地缓存中取,否则就会返回最新的资源。由Last-Modified/If-Modified-Since和Etag/If-None-Match决定。

A、Last-modified/If-Modified-Since
服务端文件的最后修改时间,需要结合cache-control使用。当浏览器首次请求资源R时,请求的Header中没有If-Modified-Since。响应状态码为200,响应的Header中返回了Last-Modified和资源R。当浏览器再次请求时,请求的Header携带了If-Modified-Since,其值为上次响应的Last-Modified的时间,询问Last-Modified时间点之后资源是否被修改过,如果修改了,就返回304,使用缓存。如果没有修改,则再去服务器请求资源,返回200,资源为服务器最新资源。

B、ETag/If-None-Match
Etag/If-None-Match也要配合Cache-Control使用。
服务端对文件的索引节,大小,最后修改时间进行hash得到etag。当浏览器首次请求资源R时,请求的Header中没有If-None-Match。响应状态码为200,响应的Header中返回了etag和资源R。当浏览器再次请求R时,请求的Header携带了If-None-Match,其值为上次响应的etag。服务端再次计算哈希值,与浏览器的etag进行比较。如果etag相同,就返回304,使用缓存。如果etag不同,就返回200,响应的Header中返回最新的etag和资源R。

C、使用ETag可以解决Last-modified存在的一些问题

  • Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间(无法及时更新文件)
  • 如果某些文件被定期生成,内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存,而ETag会认为资源还是没有修改的。

三、缓存有利有弊
1、好处

  • 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度。
  • 节省带宽:对于已缓存的文件,可以减少请求带宽甚至无需请求网络。
  • 降低服务器压力:在大量用户并发请求的情况下,服务器的性能受到限制,此时将一些静态资源放置在网络的多个节点,可以起到均衡负载的作用,降低服务器的压力。

2、弊端
然而在版本升级或做一些css、js等调整的时候,缓存导致用户无法显示更新后的样式,这是另人头疼的问题。除非用户自行手动升级缓存,不过几乎所有用户不会为了正常访问这个网站而去手动清除缓存,因为用户根本不知道是不是缓存的问题,而归根结底,用户就是认为你的页面存在问题,不能正常访问。
3、禁用缓存

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0"> 

四、CDN缓存
内容分发网络,尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。其目的是使用户可就近取得所需内容,解决Internet网络拥挤的状况,提高用户访问网站的响应速度。
解决CDN缓存问题有3种方法:版本号时间戳MD5码

原文地址:https://www.cnblogs.com/camille666/p/cookie_session_cache.html