We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
缓存是一个比较大的知识点,同时也是一个极大提高性能的点,缓存有很多种,常见的有浏览器缓存、服务器缓存、代理服务器缓存、CDN缓存
首先谈下浏览器中的两种缓存策略,强缓存和协商缓存
强缓存是在加载资源的时候,根据请求头部的expires和cache-control判断是否命中缓存,是则直接从缓存中读取资源,不会发送请求到服务器
expires
cache-control
如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过last-modified和etag验证资源是否命中协商缓存,如果命中,服务器会发送304响应给浏览器,浏览器根据返回的报文更新缓存中的数据,但是不会返回这个资源的数据,依然是从缓存中读取资源
last-modified
etag
如果协商缓存没有命中,则直接返回给客户端新的数据
1)Expires
这是http1.0中提到的一个表示过期时间的Header,他描述的是一个绝对时间,由服务器返回,这个字段受限于本地时间,如果本地时间,可能造成缓存失效,目前H5中也可以通过meta标签来给页面设置缓存<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00"/>
meta
<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00"/>
2)Cahce-Control
max-age浏览器会第一期请求的时候设置的资源有效期,这是一个相对的值,后面浏览器在请求资源的时候,会根据此时的值来计算出一个资源过期时间,然后通过这个时间进行强缓存判断
max-age
no-cache浏览器会缓存到本地,但是每次请求数据都需要从源服务器中请求进行协商缓存
no-cache
no-store才是真正的不存储数据到本地
no-store
public可以被多用户缓存(终端、CDN中间服务器)
public
private只能被终端浏览器缓存(私有缓存),不允许中继缓存服务器进行缓存
private
当协商缓存命中,请求响应返回的Http状态是304并且显示一个Not Modified的字符,协商缓存主要使用西下面这几个字段来进行控制
1)Last-Modified、If-Modified-Since
Last-Modified表示本地文件最后修改日期,浏览器会在请求头部加上If-Modified-Since(上次返回的Last-Modified),询问服务器在该日期后资源是否有更新,有更新的话会将新的资源发送回来
Last-Modified
If-Modified-Since
如果本地打开缓存文件,就会造成Last-Modified被修改,所以在Http/1.1出现了Etag
2)ETag、If-None-Match
ETag就是一个hash,资源内容的变化都会导致Etag变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的
ETag
If-None-Match的header会将上次返回的Etag发送给服务器,询问该资源的ETag是否有更新,有变动就会发送新的资源回来
If-None-Match
Etag
Etag的优先级比Last-Modified更高
具体为什么要使用Etag,主要出于下面几种情况的考虑:
GET
1、在URL输入栏中输入然后回车
浏览器会针对文件进行缓存,直到该文件过期、用户清空cache或者用户强制刷新资源时间
2、F5/点击工具栏中的刷新按钮/右键菜单重新加载
每个资源都需要进行协商缓存,忽略强缓存的相关字段。
3、ctrl+F5
彻底从服务器,拿到一份新的资源过来,所以不光要发送请求给server,而且这个请求要将所有协商缓存控制头去掉,这种的操作全部返回的是200,并刷新了相关缓存的控制时间
实际上保证为了拿到是从服务器上最新的代码,还需要添加一些HTTP Headers,按照Http/1.1协议,Cache不仅仅是存在于浏览器端,从浏览器到Server的中间节点也可能扮演者Cache的作用,为了防止获得的只是这些中间节点的Cahche,需要告诉他们,别用自己的缓存的数据来敷衍我,往Upstream节点要一个最新的copy
Cache-Control: no-cache Pragma: no-cache
这里我们需要知道另外两个头部,一个是Date,另一个是Age字段来得到答案。
Date 理所当然是源服务器发送该资源响应报文的时间(GMT格式),如果你发现 Date 的时间与“当前时间”差别较大,或者连续F5刷新发现 Date 的值都没变化,则说明你当前请求是命中了代理服务器的缓存。
Age是响应报文中的首部字段,他表示该文件在代理服务器中存在的时间,如文件被修改或者替换,Age会重新从0开始累计。
首先明确浏览器会存在两个字段,一个Expires(一个绝对时间),Max-age指的是从文档被访问后的存活时间,这个时间是相对时间,相对于文档被第一次请求的Request_time(请求时间),在Apache中,max-age是根据Expires的时间来计算出来的max-age = expires- request_time:(mod_expires.c),因为Expires中的时间是根据服务器端的时间来生成的,这样的话就存在一个问题,如果本地时间和服务器端时间相差很大的话就会产生很大的误差,Expries = Max-age + requestz_time,我们其实根据Date字段和Expires字段和Max-age和Age字段来计算目前是否进行强缓存
Request_time
Expires
max-age = expires- request_time:(mod_expires.c)
根据上面的分析我们可以知道,缓存的优先级是Cache-Control > Expires > ETag > Last-Modified
Cache-Control > Expires > ETag > Last-Modified
这个字段是设置中间服务器的缓存时间,想象这样一种情况,我们设置max-age为一年,但是如果代理服务器上也遵守这样的缓存策略,那么代理也需要将资源缓存一年,这种就是在浪费代理服务器的资源,所以为了保证代理服务器有不一样的缓存策略,我们使用s-maxage来处理代理服务器的相关缓存设置,针对代理服务器会优先考虑s-maxage,这样我们才可以对代理服务器设置不同的缓存策略。
s-maxage
The text was updated successfully, but these errors were encountered:
No branches or pull requests
缓存是一个比较大的知识点,同时也是一个极大提高性能的点,缓存有很多种,常见的有浏览器缓存、服务器缓存、代理服务器缓存、CDN缓存
首先谈下浏览器中的两种缓存策略,强缓存和协商缓存
强缓存是在加载资源的时候,根据请求头部的
expires
和cache-control
判断是否命中缓存,是则直接从缓存中读取资源,不会发送请求到服务器如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过
last-modified
和etag
验证资源是否命中协商缓存,如果命中,服务器会发送304响应给浏览器,浏览器根据返回的报文更新缓存中的数据,但是不会返回这个资源的数据,依然是从缓存中读取资源如果协商缓存没有命中,则直接返回给客户端新的数据
1、强缓存
1)Expires
这是http1.0中提到的一个表示过期时间的Header,他描述的是一个绝对时间,由服务器返回,这个字段受限于本地时间,如果本地时间,可能造成缓存失效,目前H5中也可以通过
meta
标签来给页面设置缓存<meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00"/>
2)Cahce-Control
max-age
浏览器会第一期请求的时候设置的资源有效期,这是一个相对的值,后面浏览器在请求资源的时候,会根据此时的值来计算出一个资源过期时间,然后通过这个时间进行强缓存判断no-cache
浏览器会缓存到本地,但是每次请求数据都需要从源服务器中请求进行协商缓存no-store
才是真正的不存储数据到本地public
可以被多用户缓存(终端、CDN中间服务器)private
只能被终端浏览器缓存(私有缓存),不允许中继缓存服务器进行缓存2、协商缓存
当协商缓存命中,请求响应返回的Http状态是304并且显示一个Not Modified的字符,协商缓存主要使用西下面这几个字段来进行控制
1)Last-Modified、If-Modified-Since
Last-Modified
表示本地文件最后修改日期,浏览器会在请求头部加上If-Modified-Since
(上次返回的Last-Modified
),询问服务器在该日期后资源是否有更新,有更新的话会将新的资源发送回来如果本地打开缓存文件,就会造成
Last-Modified
被修改,所以在Http/1.1出现了Etag2)ETag、If-None-Match
ETag
就是一个hash,资源内容的变化都会导致Etag变化,跟最后修改时间没有关系,ETag
可以保证每一个资源是唯一的If-None-Match
的header会将上次返回的Etag
发送给服务器,询问该资源的ETag
是否有更新,有变动就会发送新的资源回来Etag
的优先级比Last-Modified
更高具体为什么要使用
Etag
,主要出于下面几种情况的考虑:GET
3、状态码的区别
4、选择缓存的时候需要注意
Last-Modified
必须保持一致,以免负载均衡到不同机器导致比对失败头部 | 优势和特点 | 劣势和问题
-- | -- | --
Expires | 1、HTTP 1.0 产物,可以在HTTP 1.0和1.1中使用,简单易用。 2、以时刻标识失效时间。 | 1、时间是由服务器发送的(UTC),如果服务器时间和客户端时间存在不一致,可能会出现问题。 2、存在版本问题,到期之前的修改客户端是不可知的
Cache-Control | 1、HTTP 1.1 产物,以时间间隔标识失效时间,解决了Expires服务器和客户端相对时间的问题。 2、比Expires多了很多选项设置。 | 1、HTTP 1.1 才有的内容,不适用于HTTP 1.0 。 2、存在版本问题,到期之前的修改客户端是不可知的。
Last-Modified | 1、不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。 | 1、只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。 2、以时刻作为标识,无法识别一秒内进行多次修改的情况。 3、某些服务器不能精确的得到文件的最后修改时间。
ETag | 1、可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。 2、不存在版本问题,每次请求都回去服务器进行校验。 | 1、计算ETag值需要性能损耗。 2、分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时发现ETag不匹配的情况。
5、用户刷新/访问行为
1、在URL输入栏中输入然后回车
浏览器会针对文件进行缓存,直到该文件过期、用户清空cache或者用户强制刷新资源时间
2、F5/点击工具栏中的刷新按钮/右键菜单重新加载
每个资源都需要进行协商缓存,忽略强缓存的相关字段。
3、ctrl+F5
彻底从服务器,拿到一份新的资源过来,所以不光要发送请求给server,而且这个请求要将所有协商缓存控制头去掉,这种的操作全部返回的是200,并刷新了相关缓存的控制时间
实际上保证为了拿到是从服务器上最新的代码,还需要添加一些HTTP Headers,按照Http/1.1协议,Cache不仅仅是存在于浏览器端,从浏览器到Server的中间节点也可能扮演者Cache的作用,为了防止获得的只是这些中间节点的Cahche,需要告诉他们,别用自己的缓存的数据来敷衍我,往Upstream节点要一个最新的copy
6、如何判断文件来源
这里我们需要知道另外两个头部,一个是Date,另一个是Age字段来得到答案。
Date 理所当然是源服务器发送该资源响应报文的时间(GMT格式),如果你发现 Date 的时间与“当前时间”差别较大,或者连续F5刷新发现 Date 的值都没变化,则说明你当前请求是命中了代理服务器的缓存。
Age是响应报文中的首部字段,他表示该文件在代理服务器中存在的时间,如文件被修改或者替换,Age会重新从0开始累计。
7、浏览器如何进行强缓存
首先明确浏览器会存在两个字段,一个Expires(一个绝对时间),Max-age指的是从文档被访问后的存活时间,这个时间是相对时间,相对于文档被第一次请求的
Request_time
(请求时间),在Apache中,max-age
是根据Expires
的时间来计算出来的max-age = expires- request_time:(mod_expires.c)
,因为Expires中的时间是根据服务器端的时间来生成的,这样的话就存在一个问题,如果本地时间和服务器端时间相差很大的话就会产生很大的误差,Expries = Max-age + requestz_time,我们其实根据Date字段和Expires字段和Max-age和Age字段来计算目前是否进行强缓存8、字段优先级问题
根据上面的分析我们可以知道,缓存的优先级是
Cache-Control > Expires > ETag > Last-Modified
9、s-maxage字段
这个字段是设置中间服务器的缓存时间,想象这样一种情况,我们设置max-age为一年,但是如果代理服务器上也遵守这样的缓存策略,那么代理也需要将资源缓存一年,这种就是在浪费代理服务器的资源,所以为了保证代理服务器有不一样的缓存策略,我们使用
s-maxage
来处理代理服务器的相关缓存设置,针对代理服务器会优先考虑s-maxage
,这样我们才可以对代理服务器设置不同的缓存策略。The text was updated successfully, but these errors were encountered: