码迷,mamicode.com
首页 > 其他好文 > 详细

浏览器缓存剖析

时间:2019-12-09 01:42:44      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:etag   返回   备份   服务器端   none   手动   响应头   expr   步骤   

浏览器缓存是优化网站,提升网站性能的有效方法。

浏览器缓存一般指对服务器返回静态资源(html、js、css文件,图片,数据)在客户端的备份。(不考虑ajax请求)

 

??基于Chrome浏览器版本 78.0.3904.97(正式版本);firefox默认过期时间都是0,设置其他值也无效。

1. 浏览器缓存策略

 

浏览器缓存策略指的是,先判断是否允许浏览器缓存。

1. http1.0对应的header

通过HeaderEditor的Chrome插件模拟实现。

1. 请求头字段(Request Header)

/*** Pragma决定是否允许资源缓存;*****/
Pragma: no-cache  
// 对于index.html只设置这一个字段,就不允许缓存
// 对于js/css文件来说,如果没有设置Cache-Control,根据响应头判断
// ??开发者工具中的Disable Cache开启后,浏览器自动设置
Pragma: no-cache;
Cache-Control: no-cache;

2. 响应头字段(Response Header)

该字段默认不添加;

Expires: new Date(...) //GMT格式时间
// 表示允许缓存,且指定了缓存资源的过期时间
// 当没有Cache-Control时,该字段起作用,API在过期时间内从缓存取值
// 如果响应头中出现Cache-Control,该字段直接被忽略

2. http1.1对应的Header

1. 请求头字段(Request Header)

//指定不允许缓存资源
Cache-Control: no-cache;
只对index.html有效
// 浏览器刷新时,index.html页面自动携带Cache-Control: max-age=0
// 相当于响应头中的Cache-Control: no-cache
Cache-Control: max-age=0 
// 允许缓存;即时过期,进入协商缓存阶段

其他值测试都无效果

2. 响应头字段(Response Header)

对于静态资源请求,服务器会自动携带Cache-Control: public, max-age=0

对于ajax请求,默认没有Cache-Control字段,需要手动设置

/** Express启动的应用,html, js,css文件默认返回的值;**/
Cache-Control: public,max-age=0 
// public: 表示服务器允许客户端,CDN等代理服务器等缓存
// max-age: 允许缓存,并且缓存过期时间是0,下次请求就会进入协商缓存;
Cache-Control: private
// 只允许客户端缓存
这个值和请求头中的行为不一致
Cache-Control: no-cache
// 允许缓存,立即过期,直接进入协商缓存;
Cache-Control: no-store
// 不允许缓存资源;相当于请求头中的no-cache
index.html无效;它即使在过期时间内,也直接执行协商缓存;
// js文件有效。再次访问,在缓存过期时间内,直接从内存中获取,状态码200(from memory cache),不会向服务器发起请求;过期后进入协商缓存阶段
Cache-Control: max-age=5  //  5秒
// 允许缓存,并且过期时间距离响应返回时间5秒;5秒内直接从缓存中取值,5秒后请求进入协商缓存

2. 缓存协商策略

协商策略是在本身有缓存,但是缓存过期后的请求规则。

对于静态资源资源请求,服务器会自动添加对应的字段。

1. http1.0协商缓存字段

1. Last-Modified(响应头)/If-Modified-Since(请求头)

只能精确到秒,精确度比较低

Last-Modified: Tue, 04 Apr 2017 10:01:15 GMT  // GMT时间格式;只能精确到秒
If-Modified-Since: Tue, 04 Apr 2017 10:01:15 GMT  // GMT时间格式

1)如果某接口初次加载的时候允许缓存,客户端会将响应头和返回的内容进行缓存。再次请求的时候去缓存区根据缓存的响应头max-age/Expires判断,缓存是否过期;

2)如果没有过期,直接从缓存获取内容,不再向服务器发送请求,对应的状态码200(from memory cache/from dish cache);

3)如果已经过期, 从缓存的响应头中取出Last-Modified的值,赋值给请求头的If-Modified-Since,发起请求,在服务器端将If-Modified-Since的值和被请求资源的Last-Modified比较。

如果相同,则说明资源没有修改,返回304,然后浏览器去缓存区获取内容。如果不同,说明资源已经修改,服务器返回200, 返回最新的资源,更新响应头,并更新缓存区内容。

2. Etag(响应头)/If-None-Match(请求头)

优先级高于Last-Modified,如果共存,会先判断Etag

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"  //唯一标识符号
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

ETag: W/"0815" // W/表示弱验证
If-None-Match: W/"0815" 

1)同上面第一步,先判断是否过期。

2)如果没有过期,从缓存区返回数据,响应状态码为200(from memory cache/from dish cache)。

3)如果过期,从缓存区响应头取出Etag的值,赋值给请求头If-None-Match字段,向服务器发起请求。在服务器端将If-None-Match和被请求资源的Etag比较。

如果相同,说明资源未改变,服务器返回304,浏览器去缓存区获取资源;如果不同,说明资源修改,返回200,同时更新响应头,返回最新的资源,并更新缓存区内容。

3. 浏览器缓存步骤

1. 浏览器发起请求,浏览器根据请求头的Pragma/Cache-Control或者响应头Cache-Control来判断,初次请求返回结果是否要进行缓存。

2.如果允许缓存,浏览器将响应头和响应内容全部缓存在客户端。

3. 再次发起请求,浏览器到缓存区根据之前缓存的响应头中Expires/Cache-Control判断缓存是否过期。

4.如果未过期,则直接从缓存区返回内容,并返回状态码200(from memory cache/from dash cache)。如果缓存过期,浏览器向服务器再次发起请求,并携带If-None-Macth/If-Modified-Since字段,两个字段分别对应之前缓存的Etag/Last-Modified字段。

5. 服务器再次接受到请求,根据携带的If-None-Macth/If-Modified-Since字段,分别和服务器端资源的Etag/Last-Modified比较。如果相同,说明资源未经过修改,则只返回响应头,不返回资源内容,响应状态码为304,浏览器接收到304,再到缓存区取出数据,并更新过期时间。如果不相同,说明资源经过了修改,服务器返回200,并返回最新的资源,更新响应头对应的Etag/Last-Modified,再次将新的响应内容进行缓存,更新缓存区的内容,然后将响应内容返回给浏览器。

4. 强制更新/废弃缓存内容

强制不适用缓存资源。

1. 问题描述:

用户从收藏夹点击进入网站,浏览器加载的index.html文件始终是旧文件。

解决办法:

在服务器端,设置返回index.html文件的响应的时候,响应头设置Cache-Control: no-store不允许缓存或者Cache-Control: max-age=0/no-cache只允许协商缓存。

2. 问题描述:

如果资源文件(js/css等)设置的缓存过期时间特别久,则浏览器会一直从本地缓存资源获取文件,不向服务器发出请求。一直获取不到最新的文件。

解决办法:

1)修改引入文件的文件名(添加hash后缀)

将js/css文件添加hash后缀。对于浏览器来说,文件后缀修改,对于浏览器来说是新的资源,会重新加载资源。

2)给引入文件路由添加时间戳

url+?timeStamp=1323123213, 浏览器也会认为是新的资源

 

浏览器缓存剖析

标签:etag   返回   备份   服务器端   none   手动   响应头   expr   步骤   

原文地址:https://www.cnblogs.com/lyraLee/p/12008688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!