💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
- 304 - 强制缓存 - Expires/Cache-Control - no-cache - 对比缓存 - Last-Modifed与if-modified-since - Etag与if-none-match - 两种缓存一起使用 - 浏览器行为 - Memory Cache 和 Disk Cache的区别 - f5和ctrl+f5 [TOC] ## 304 ``` res.statusCode = 304; ``` 当我们在响应信息中回复304时,浏览器会自动从本地的缓存数据库中拿取数据。 嗯,这句其实是缓存中最关键的一句,其它的获取设置缓存相关的头都是再为是否输出这一句话做铺垫。 ## 强制缓存 ### Expires/Cache-Control ``` res.setHeader('Expires',date.toUTCString()); res.setHeader('Cache-Control','max-age=10'); //以秒为单位 ``` `Expires`和`Cache-Control`都能起到强制缓存的作用,即在一定时间内客户端的请求会先走本地缓存而不是向服务器发起。 其中Expires是`http1.0`协议中的头,我们使用它一般都是为了兼容,值得注意的是Expires的值和Cache-Control的值是不一样的。 Expires的值要求必须是GMT格式(?嗯,印象中有人这么说过,反正我不用。。。),而Cache-Control值的格式则为`max-age=xxx`,xxx是一个数字,是一个相对时间,单位为**秒**。 #### no-cache 当`Cache-Control`置为`no-cache`时,客户端每次请求都**会先忽略本地缓存**直接向服务端询问是否要采用缓存。 ## 对比缓存 ### Last-Modifed与if-modified-since 根据文件的修改时间是否发生改变来决定是否采取缓存。 ``` res.setHeader('Last-Modified',stat.ctime.toUTCSting()); ``` ``` let since = req.headers['if-modified-since']; if(since){ if(since === stat.ctime.toUTCString()){ //没有被修改 res.statusCode = 304; //让它去缓存中找 res.end(); }else{ sendFile(req,res,p,stat); } }else{ sendFile(req,res,p,stat); } ``` >**注意:** 这个时间格式并没有强制的限制,但我们要注意在使用中要保持格式的一致。 ### Etag与if-none-match 根据文件的内容是否发生改变来决定是否采取缓存。 ``` function sendFile(req,res,p,stat){ res.setHeader('Cache-Control','no-cache'); //不走本地缓存,会向服务器询问 res.setHeader('Etag',r); res.setHeader('Content-Type',mime.getType(p)+';charset=utf8'); ... } ``` ``` ... let md5 = crypto.createHash('md5'); let rs = fs.createReadStream(p); rs.on('data',function(data){ md5.update(data); }); rs.on('end',function(){ let r = md5.digest('hex'); //对当前文件进行摘要 let ifNoneMatch = req.headers['if-none-match']; if(ifNoneMatch){ if(ifNoneMatch===r){ res.statusCode = 304; res.end(); }else{ sendFile(req,res,p,r); } }else{ sendFile(req,res,p,r); } }) ... ``` 如果文件过大时,进行摘要是很不实际的,So我们一般选择ctime+size作为`Etag`的值。 ## 两种缓存一起使用 一般来说会同时使用上以上两种缓存,这个时候会先看强制缓存是否过期,没有过期就会从本地缓存中拿数据,**只有过期了才会向服务器询问**,这样有利于减轻服务器的鸭梨。 ## 浏览器行为 ### Memory Cache 和 Disk Cache的区别 Memory Cache 和 Disk Cache 是浏览器缓存的两种模式。 笔者也不是很了解,这里抛出只是为了完善体系,这里给出一些社区的回答 ![](https://box.kancloud.cn/4d387e06b77aebbe85d80e928dd2b195_1650x488.png) > [原文](https://stackoverflow.com/questions/44596937/chrome-memory-cache-vs-disk-cache ) ### f5和ctrl+f5 f5:跳过强制缓存,但是会检查协商缓存 ctrl+f5:跳过强制缓存和协商缓存,服务器重新发送数据给浏览器