前端缓存

前端缓存可分为两大类:http缓存和浏览器缓存。我们今天重点讲的是http缓存,所以关于浏览器缓存大家自行去查阅。下面这张图是前端缓存的一个大致知识点:

HTTP 缓存策略分为两种: 强缓存 和 协商缓存 ,这两种缓存策略都是服务端设置 HTTP Header 来实现的

(一)强缓存

强缓存的意思很简单,直接从浏览器缓存过的本地进行读取,不会去请求服务器。例如请求一个图片,当缓存后,第二次访问,直接从本地去拿,不会再去请求这个资源,可以节省服务器资源。可以通过三种方式来设置强缓存

Expires:服务端在响应头中设置一个 GMT 格式的到期时间。客户端的本地时间小于响应头的 Expires 时间,那么会从本地进行读取,不会去请求服务器。如果超过了,那么就去请求服务器去获取最新资源。但是就是因为根据本地时间进行判断,本地时间可以随便修改,所以这种缓存机制有漏洞,会与服务端时间有偏差,为了解决这个问题,就出现了下面的 Cache-contorl
Cache-control:他和Expires不一样,Expires是直接设置一个时间戳就行了,而Cache-control可以设置下面这几种属性:

max-age:这个用于设置一个滑动时间,例如设置 max-age=30 表示客户端时间向后滑动30秒,在这30秒内都是强缓存,不会去请求服务器
s-maxage:这个和上面的一样,只不过这个设置的是代理服务器的缓存时间
privte:这个表示缓存只能被客户端的浏览器缓存,不能被代理服务器缓存
public:这个表示缓存既可以被浏览器缓存,也可以被代理服务器缓存
no-store:这个属性表示不缓存,在任何情况下,都是与服务器进行最新的交互
no-cache:这个并非不缓存的意思,这个表示强制进行协商缓存,会在下面描述

(二)协商缓存

协商缓存表示在使用本地的缓存之前,会先向服务器发一个请求,与服务器协商当前浏览器的缓存是否已经过期了,如果没过期,那么就使用本地的资源,如果过期了就去请求最新资源。协商缓存主要是解决强缓存资源不能及时更新的问题,协商缓存服务端可以通过2种设置来实现:

第一种:last-modified 配合 If-Modified-Since

例如,客户端请求一个 03.jpg,服务端接收到这个请求后,会读取这个文件的最后修改时间,然后设置到响应头中,设置的参数就是 last-modified,参数值是文件最后修改的时间戳。客户端第二次请求 03.jpg 这个文件的时候,会带上一个 If-Modified-Since 参数,服务端能拿到这个参数与last-modified进行比对,如果一致,那么就返回304状态,否则就去请求最新的文件,使用nodejs实现这个代码:(注意协商缓存需要设置Cache-Control为no-cache,表示设置成协商缓存)
...
// 判断客户端请求的是03这个图片
if(pathname === '/img/03.jpg') {
// 读取 03 图片的最后修改时间
const { mtime } = fs.statSync("./img/03.jpg")
// 判断客户端发送过来的if-modified-since是否与mtime一致,如果一致就直接返回304
if(req.headers['if-modified-since'] === mtime.toUTCString()) {

res.statusCode = 304
res.end()

} else {

// 如果不一致,那么就请求最新的资源返回给客户端
const data = fs.readFileSync("./img/03.jpg")
// 这2句代码是设置协商缓存
res.setHeader("last-modified", mtime.toUTCString())
res.setHeader("Cache-Control", "no-cache")
res.end(data)

}
}
...
上面的 last-modified 配合 If-Modified-Since在使用时有些弊端,例如将03.jpg修改成04.jpg,再改回03.jpg。此时这个文件其实是没有变化的,但是最后修改时间更改了,因此客户端就需要重新请求,因此就出现了下面的第二种使用Etag的方式

第二种:Etag 配合 If-None-Match

Etag实现的方式服务端是为文件生成一个指纹,类似于MD5字符串。接着响应头中塞进 Etag 参数,参数的值就是计算出的字符串,客户端接收到后,第二次请求会带上一个 If-None-Match 的参数,接着服务端和上面第一种方式一样进行比对,nodejs的实现代码如下:
// 引入 etag 模块
const etag = reqiure("etag")
...
if(pathname === '/img/03.jpg') {
const data = fs.readFileSync("./img/03.jpg")
// 获取生成的etag字符串
const etag = etag(data)
// 判断客户端发送的 If-None-Match 与服务端是否一致
if(req.headers['if-none-match'] === etag) {

res.statusCode = 304
res.end()

} else {

// 如果不一致,那么就请求最新的资源返回给客户端
const data = fs.readFileSync("./img/03.jpg")
// 这2句代码是设置协商缓存
res.setHeader("etag", etag)
res.setHeader("Cache-Control", "no-cache")
res.end(data)

}
}
...

0

版权属于: liangliang

本文链接: https://blog.yanjiubu.com/archives/8.html

HTTP缓存最详细的两种方法相关推荐

  1. WAS启动控制台,但不自动启动应用(详细配置两种方法)

    WAS启动控制台但不自动启动应用 一.was控制台的启停命令 一般情况下WAS控制台的启停脚本在bin目录下,此处默认server1.本文的WAS版本为9.0.0.9 #cd /washome/IBM ...

  2. Android4清理代码缓存,Android清除应用缓存的两种方法

    第一种 使用ActivityManager中的clearApplicationUserData方法,代码如下: ActivityManager am = (ActivityManager) getSy ...

  3. 计算机cpu 二级缓存,Windowsxp系统开启cpu二级缓存的两种方法

    WindowsXP系统的CPU二级缓存在默认情况下是处于关闭状态的.一些用户为了发挥出CPU的最大效率,就希望能打开CPU二级缓存.这该如何操作呢?接下来,系统城小编就为大家详细介绍xp系统cpu打开 ...

  4. Database之SQLSever:SQLSever数据表管理(GUI法/SQL语句命令法两种方法实现建立表、修改表,以及增、删、改、查)之详细攻略

    Database之SQLSever:SQLSever数据表管理(GUI法/SQL语句命令法两种方法实现建立表.修改表,以及增.删.改.查)之详细攻略 目录 一.两种方法建立表.修改表,插入多条数据记录 ...

  5. Database之SQLSever:SQLSever数据库管理(GUI法/SQL语句命令法两种方法实现备份(完整备份、差异备份、日志备份)、还原、删除、修改数据库等案例)之详细攻略

    Database之SQLSever:SQLSever数据库管理(GUI法/SQL语句命令法两种方法实现备份(完整备份.差异备份.日志备份).还原.删除.修改数据库等案例)之详细攻略 目录 数据库管理 ...

  6. 修改mysql数据库默认字符集_MySQL数据库之修改mysql默认字符集的两种方法详细解析...

    本文主要向大家介绍了MySQL数据库之修改mysql默认字符集的两种方法详细解析 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. (1) 最简单的修改方法,就是修改mysql的m ...

  7. c语言mfc怎么插入背景图片,MFC 对话框添加背景图片详细过程(两种方法)

    给对话框添加背景图片方法很多,在此贴出两种很常见的方法.一种是通过读取位图资源显示位图(BitMap) step: 1.创建内存设备上下文: 2.选择位图,将其装入内存设备上下文: 3.使用BitBl ...

  8. 基于R和ArcGIS两种方法制作土地利用转移图详细教程

    Part1背景 土地利用转移矩阵大家应该都会做,但是土地利用转移图还是有部分人不太会做,本期介绍下R和ArcGIS两种方法绘制土地利用转移图,大家多多分享.练习数据来源请引用:地理遥感生态网科学数据注 ...

  9. MFC 对话框添加背景图片详细过程(两种方法)

    给对话框添加背景图片方法很多,在此贴出两种很常见的方法.一种是通过读取位图资源显示位图(BitMap) step: 1.创建内存设备上下文: 2.选择位图,将其装入内存设备上下文: 3.使用BitBl ...

最新文章

  1. Spring4-JdbcDaoSupport-查询单列
  2. opencv-python图像处理之让你的照片变旧
  3. python模型训练效果没有优化_LSTM模型训练效果好,但测试结果较差,不能看出拟合过度...
  4. mysql delimiter 作用
  5. java ftp复制文件_如何使用Java将FTP服务器上的文件复制到同一服务器上的目录中?...
  6. linux学习作业-第七周
  7. 银行有没有可能把800元存款打成80万?如果发生该怎么办?
  8. oracle中的常用函数
  9. IDEA 启动时,报“淇℃伅”的字符
  10. Nginx 的 Location 配置指令块
  11. @import与link方式的区别
  12. 小白系列:修改美化pycharm主题
  13. 铁路、公路施工企业劳务实名制管理系统解决方案
  14. 【GDOI2014模拟】​Pty爬山
  15. 【我的Android进阶之旅】Configuration 'compile' is obsolete and has been replaced with 'implementation' and
  16. 程序员常用官网和工具站
  17. python 开放端口探测工具
  18. linux防护勒索病毒的补丁,抵御Petya勒索病毒的最新办法
  19. ATTCK 1一个烂尾的学习记录
  20. 湖仓一体电商项目(一):项目背景和架构介绍

热门文章

  1. Vue显示图片的几种方式
  2. 【面试集锦 - C语言 - 单元测试】
  3. Linux删除目录非空的文件夹命令
  4. 2020最全影视站解析接口
  5. lower_bound()
  6. 1.Linux命令-删除
  7. 用matlab画水晶球,Flash CS4的Deco工具绘制一个有图案的水晶球
  8. 鸿蒙一号指纹锁怎么样,很多人不知道,安了耶鲁指纹锁YMH71后还可以这样开门...
  9. Mac照片误删恢复|mac误删照片怎么恢复?
  10. 计算机房电脑忽然黑屏,主机正常运行显示器黑屏显示无信号