文对强缓存和弱缓存进行讲解:
为了展示强缓存和弱缓存
第一步:Ctrl + shift + delete将缓存给清除
将浏览器的数据给清空一下
这里的数据大小是83.4kB
在响应头里面,会存在着ETag和Last-Modified资料
第一请求和第二请求,这里多了一个If-Modified,在弱缓存当中,从缓存中获取数据,检验匹配是经过多次匹配,出现304指令,
200或者304指令意味着没有发生变化
如果是强缓存这里根本不会产生数据,强缓存的特性是存储在用户的本地
浏览器缓存相关指令
expires指令
expires:该指令用来控制页面缓存的作用。可以通过该指令控制HTTP应 答中的“Expires"和”Cache-Control"
expires 有两种语法,一种是time,time是时间值,它默认是以秒来计数的
no-cache,无论缓存有没有过期,都需要发送请求,检验缓存有没有过期
max-age与expires的意思差不多,只不过有的没有这个配置,
epoch会指定1970的时间,max是2037年的时间
具体配置流程:
vim ngnix.conf
为了方便对比,先将请求头信息进行复制
之后在conf配置文件下配置
location ~ .*\.(html|js|css|png) $ {
}
以html和js和css等结尾的资源,都走这个
写成expiress 1000;的意思是缓存1000s
检验语法,重新加载
重新对jQuery.js中进行查看
现在相应头多了一块时间max-age=1000秒和Expires:Mon.27(Expires的意思是服务器的时间)
如果将配置expiress修改为-1000,改为了负数,在请求头中出现了no-cache
如果将该值指定为max
它会出现一些时间,默认是以秒来分割的
这个max的值是10年的意思,意思是最大的缓存时间可以已达到10年
add_header指令
add_header指令是用来添加指定的响应头和响应值。
语法 add_header name value [always];
位置存储在http、server、location..
如果想要到web服务器直接获取,不缓存,用no-store
不缓存的写法配置,在配置文件中添加add_header Cache-Control no-store
现在就实现了弱缓存,第一次访问了304kb数据,第二次就是83.5kb,实现了弱缓存了
Web 缓存是可以自动保存常见文档副本的 HTTP 设备。当 Web 请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取这 个文档。
一个缓存从接收到请求到做出响应,大概可以分为如下7个步骤:
项目中,我们主要使用缓存来存储html、css、js、img等静态资源,一般不会去存储动态资源,因为对动态资源的缓存会对数据实时性造成影响
强缓存是当我们访问URL的时候,不会向服务器发送请求,直接从缓存中读取资源,但是会返回200的状态码。
我们第一次进入页面,请求服务器,然后服务器进行应答,浏览器会根据response Header来判断是否对资源进行缓存,如果响应头中expires、pragma或者cache-control字段,代表这是强缓存,浏览器就会把资源缓存在memory cache 或 disk cache中。
第二次请求时,浏览器判断请求参数,如果符合强缓存条件就直接返回状态码200,从本地缓存中拿数据。否则把响应参数存在request header请求头中,看是否符合协商缓存,符合则返回状态码304,不符合则服务器会返回全新资源。
这是 http1.0 时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2022 21: 31 :12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。
Expires过度依赖本地时间,如果本地与服务器时间不同步,就会出现资源无法被缓存或者资源永远被缓存的情况。所以,Expires字段几乎不被使用了
上面我们提到了Expires有个缺点,当客户端本地时间和服务器时间不一致时会产生误差,浏览器会直接向服务器请求新的资源,为了解决这个问题,在http1.1规范中,提出了cache-control字段,且这个字段优先级高于上面提到的Expires,值是相对时间。
上面提到的强缓存都是由本地浏览器在确定是否使用缓存,当浏览器没有命中强缓存时就会向浏览器发送请求,验证协商缓存是否命中,如果缓存命中则返回304状态码,否则返回新的资源数据。
协商缓存(也叫对比缓存)是由服务器来确定资源是否可用,这将涉及到两组字段成对出现的,在浏览器第一次发出请求时会带上字段(Last-Modified或者Etag),则后续请求则会带上对于的请求字段(if-modified-since或者if-none-Match),若响应头没有Last-Modified或者Etag,则请求头也不会有对应的字段
const http = require('http');
const fs = require('fs');
http.createServer((req,res)=>{
if(req.url === 'test.png'){
const data = fs.readFileSync('./test.png');
const {mtime} = fs.statSync('./test.png');
const temp = req.headers['if-modified-since'];
if(temp === mtime.toUTCString()){
res.statusCode = 304;
res.end();
return;
}
res.setHeader('last-modified',mtime.toUTCString());
res.setHeader('Catch-Control','no=cache');
res.end(data);
}else{
res.end(fs.readFileSync('./test.html'));
}
})
const http = require('http');
const fs = require('fs');
const etag = require('etag');
http.createServer((req,res)=>{
if(req.url === 'test.png'){
const data = fs.readFileSync('./test.png');
const etagContent = etag(data);
const noMatch = req.headers['if-none-match'];
if(noMatch === etagContent){
res.statusCode = 304;
res.end();
return;
}
res.setHeader('etag',etagContent);
res.setHeader('Catch-Control','no=cache');
res.end(data);
}else{
res.end(fs.readFileSync('./test.html'));
}
})
毕清华:精选主力干将!
来源:微信公众号:58本地服务终端技术
出处:https://mp.weixin.qq.com/s/-83N7RS1B6V_r5tcU2CyrA
试公司:
阿里
面试环节:
一面
问题:
说一说你对浏览器强缓存和协商缓存的理解
这里说的缓存是指浏览器(客户端)在本地磁盘中对访问过的资源保存的副本文件。
浏览器缓存主要有以下几个优点:
浏览器缓存分为强缓存和协商缓存,两者有两个比较明显的区别:
其中 from cache 会分为 from disk cache 和 from memory cache. 从内存中获取最快,但是是 session 级别的缓存,关闭浏览器之后就没有了。
请求流程
浏览器在第一次请求后缓存资源,再次请求时,会进行下面两个步骤:
借用网上的一张图片
强缓存
强缓存是根据返回头中的 Expires 或者 Cache-Control 两个字段来控制的,都是表示资源的缓存有效时间。
如果 Cache-Control 与 Expires 同时存在的话, Cache-Control 的优先级高于 Expires 。
协商缓存
协商缓存是由服务器来确定缓存资源是否可用。 主要涉及到两对属性字段,都是成对出现的,即第一次请求的响应头带上某个字, Last-Modified 或者 Etag,则后续请求则会带上对应的请求字段 If-Modified-Since或者 If-None-Match,若响应头没有 Last-Modified 或者 Etag 字段,则请求头也不会有对应的字段。
HTTP中并没有指定如何生成 ETag,可以由开发者自行生成,哈希是比较理想的选择。
为什么要有 Etag
HTTP1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:
优先级
Cache-Control > expires > Etag > Last-Modified
用户行为对缓存的影响
经过对qq、fire fox 、safari 、chrome 这几个浏览器的访问同一个页面测试我发现,不同的浏览器在 F5 刷新的时候 ,同一个文件 qq 、fire fox 浏览器会返回 304 Not Nodified,在请求头中不携带 Expires/Cache-Control; 而 chrome 和 safari 刷新的时候,会返回 200 from cache, 没有真正发起请求,走强缓存。可见不同的浏览器反馈是不一致的,所以下面表格中"F5刷新"时 Expires/Cache-Control 会无效我认为是存在一定争议的。
而 Ctrl + F5 强制刷新的时候,会暂时禁用强缓存和协商缓存。
如何设置强缓存和协商缓存
两个示例
三级缓存原理(大白话)
最后总结一下浏览器的三级缓存原理:
原文:https://github.com/frontend9/fe9-interview/issues/29
*请认真填写需求信息,我们会在24小时内与您取得联系。