网站首页 > 技术文章 正文
什么是缓存
缓存是浏览器的一种机制,可以把请求过的web资源(html、css、js、图片等)拷贝一份副本存储在浏览器中,并根据请求配置选择是否使用该副本。
缓存作用
- 减少网络带宽消耗
- 降低服务器压力
- 减少网络延迟,使页面的打开速度更快,增加用户体验
根据不同的划分规则,缓存可以分为以下几种:
本文只介绍浏览器的缓存机制。
浏览器缓存规则定义位置
可以在 HTTP协议头 和HTML页面的 meta标签 中定义。
meta标签定义:
<!- Pragma 是 http1.0 版本中给客户端设定缓存方式之一 ->
<meta http-equiv="Pragma" content="no-cache">
上述代码的含义:浏览器当前页面不被缓存,每次访问都向服务器请求。
http协议头定义:
与缓存有关的消息报头有expires,cache-control,Last-Modified,If-modified-since,Etag,If-none-match 等。
缓存分类
根据是否需要向服务器发送资源请求,分为 强缓存 和 协商缓存。
强缓存意味着强制使用缓存,协商缓存意味着每用一次缓存都要协商一次。 强缓存和协商缓存都允许使用情况下,优先强缓存。
强缓存
强缓存的控制字段:
- HTTP1.0:Expires
- HTTP1.1 :Cache-Control
判断过程:请求再次发起 -> 浏览器根据 expires 和 cache-control 判断目标资源是否命中"强缓存" -> 若命中,直接从缓存获取资源,不再与服务器发生通讯。
如果cache-control与expires同时存在,以cache-control为主,继续使用 expires 的目的就是向下兼容。
Expire已经被Cache-Control替代,原因在于Expires依赖于本地时间,它控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确;用户修改了本地时间)发生误差,那么强制缓存则会直接失效。
Cache-Control取值:
在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
must-revalidate: 强制浏览器严格遵守你设置的cache规则
proxy-revalidate: 强制proxy严格遵守你设置的cache规则
协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:
协商缓存生效,返回304 && 协商缓存失效,返回200和请求结果。
协商缓存流程:
协商缓存的控制字段:
- HTTP1.0:Last-Modified && If-Modified-Since
- HTTP1.1 :Etag && If-None-Match
Last-Modified 与 If-Modified-Since
Last-Modified 是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
流程:
- 首次请求
- 服务器告知启用协商缓存规则,并在响应头中带上 Last-Modified,告知缓存到期时间
- 随后的每次请求,请求头上都会携带 If-Modified-Since,该值等于上一次响应头中的 Last-Modified 的值
- 服务器收到 If-Modified-Since 后,会将该属性的值与服务器上资源的最后修改时间进行匹配,从而判断资源是否发生了变化
- 如果发生变化会返回一个完整的响应内容,在响应头中添加新的 Last-Modified 值,否则,只返回 header 部分,状态码为304,响应头不会再添加 Last-Modified
弊端: Last-Modified 无法正确感知文件的变化,譬如说,文件的编辑时间修改了而内容没有修改,或者修改文件速度太快,几毫秒就改一次文件,If-Modified-Since 只能检测秒级的变化.
为了解决这个问题,Etag 作为 Last-Modified 的升级版,因时而生。
Etag 是通过标识字符串来辨别文件内容是否发生修改的,文件内容不一致才会生成新的标识字符串,这就弥补了 Last-Modified 时间戳的不足,通过 Etag 可以精准的感知文件的变化。
Etag && If-None-Match
Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
流程:
- 首次请求
- 服务器启用协商缓存情况下,会在响应头中带上 Etag
- 随后每次请求,请求头上都会带上 If-None-Match,该值等于上一次响应头中的 Etag 的值
- 服务器收到 If-None-Match 后,会进行比对,从而判断资源是否发生变化
- 如果变化返回一个完整响应内容,在响应头上添加新的 Etag 值,否则返回 304,响应头不会在添加 Etag
弊端: Etag的生成需要服务器付出额外的开销,会影响服务端性能。
Etag 并不能替代 Last-Modified,只能作为 Last-Modified 的补充和强化存在,当 Etag 和 Last-Modified 同时出现时,以 Etag 为准。
整个缓存机制的流程图:
不能被缓存的请求
- HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
- 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
- 经过HTTPS安全加密的请求
- POST请求无法被缓存
- HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存
用户操作行为与缓存
浏览器中的操作对缓存的影响
- 强制刷新 – 当按下ctrl+F5来刷新页面的时候, 浏览器将绕过各种缓存(本地缓存和协商缓存), 直接让服务器返回最新的资源
- 普通刷新 – 当按下F5来刷新页面的时候,浏览器将绕过本地缓蹲来发送请求到服务器, 此时, 协商缓存是有效的
- 回车或转向 – 当在地址栏上输入回车或者按下跳转按钮的时候, 所有缓存都生效
- 上一篇: PHP中的九大缓存技术
- 下一篇: 「缓存系列」常用缓存模式有哪些?不同业务场景适合用哪种模式?
猜你喜欢
- 2025-01-12 CDN+OpenResty 实现丝滑访问的登录态缓存站
- 2025-01-12 如何在Spring Boot中通过布隆过滤器防止缓存穿透问题?
- 2025-01-12 HTML5缓存机制浅析:移动端Web加载性能优化
- 2025-01-12 如何在 NGINX 中缓存内容
- 2025-01-12 如何解决服务器缓存过高
- 2025-01-12 白帽黑客贡献新的Web攻击方式,CDN缓存服务器成为数据泄露目标
- 2025-01-12 西部数据推出新款蓝盘机械硬盘:CMR技术,4TB 549元
- 2025-01-12 面试官:如何实现多级缓存?
- 2025-01-12 基于spring boot的注解缓存,自带轻量级缓存管理系统
- 2025-01-12 系统设计 | 缓存系统设计
你 发表评论:
欢迎- 06-24发现一款开源宝藏级工作流低代码快速开发平台
- 06-24程序员危险了,这是一个 无代码平台+AI+code做项目的案例
- 06-24一款全新的工作流,低代码快速开发平台
- 06-24如何用好AI,改造自己的设计工作流?
- 06-24濮阳网站开发(濮阳网站建设)
- 06-24AI 如何重塑前端开发,我们该如何适应
- 06-24应届生靠这个Java简历模板拿下了5个offer
- 06-24服务端性能测试实战3-性能测试脚本开发
- 561℃Oracle分析函数之Lag和Lead()使用
- 558℃几个Oracle空值处理函数 oracle处理null值的函数
- 547℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 543℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 540℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 534℃【数据统计分析】详解Oracle分组函数之CUBE
- 520℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 512℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)