浏览器缓存机制

核心说明:本文采用「通俗解读+专业知识点」结合模式,结构清晰、重点突出,可直接背诵用于面试;重点聚焦面试高频考点(强缓存、协商缓存),简化次要内容,补充面试答题技巧和常考问题,助力快速掌握核心。

一、浏览器缓存整体结构(面试开篇必背)

通俗说:浏览器缓存就是"本地仓库",访问网站时,能直接从本地拿资源就不麻烦服务器,既省时间又省流量。专业定义:浏览器对已请求过的资源进行本地存储,后续请求时优先复用本地资源,提升加载速度、降低服务器压力。

浏览器缓存主要分为三大类,面试重点考察前两类(合称HTTP缓存):

  • 1️⃣ 强缓存:最"懒"的缓存,完全不跟服务器打招呼,直接用本地缓存

  • 2️⃣ 协商缓存:比较"谨慎",会跟服务器打个招呼,由服务器决定要不要用缓存

  • 3️⃣ Service Worker 缓存:可编程缓存(面试非重点,简单了解即可,是前端进阶的缓存方式)

二、强缓存(Strong Cache)------ 面试高频重点

✅ 核心特点(必背)

通俗说:浏览器检查本地缓存,发现"没过期",就直接拿来用,根本不向服务器发请求。

专业表述:不发送HTTP请求,直接读取本地缓存资源;浏览器判断标准为「资源未过期」,此时Network面板显示状态码 200 (from disk/memory cache)(disk cache是硬盘缓存,memory cache是内存缓存,无需区分,面试提一句即可)。

1️⃣ 强缓存控制字段(核心考点)

(1)Cache-Control(优先级最高,面试重点)

通俗说:服务器给资源设定一个"保质期",浏览器在保质期内直接用缓存,过期了再找服务器。

专业示例(HTTP响应头):

http 复制代码
Cache-Control: max-age=3600

解读:表示该资源从请求成功开始,3600秒(1小时)内有效,期间再次请求无需访问服务器。

常见指令(必背,面试常考区别):

指令 通俗解读 专业作用
max-age=3600 资源保质期3600秒 指定资源的缓存有效时间(单位:秒)
no-cache 不偷懒,每次都问服务器 不使用强缓存,直接进入协商缓存流程
no-store 不存本地,每次都重新下载 完全不缓存资源,每次请求都需从服务器获取完整资源
public 谁都能存(浏览器、CDN等) 允许任何缓存节点(浏览器、代理服务器等)缓存该资源
private 只有浏览器能存 仅允许浏览器本地缓存,禁止代理服务器等中间节点缓存

(2)Expires(老版本,面试了解即可)

通俗说:服务器给资源设定一个"过期时间点",比如"2026年10月21日过期",浏览器对比本地时间,没到点就用缓存。

专业示例(HTTP响应头):

http 复制代码
Expires: Wed, 21 Oct 2026 07:28:00 GMT

核心缺点:依赖客户端(浏览器)本地时间,如果用户修改本地时间,会导致缓存判断失效(比如把时间改成过期后,缓存直接失效)。

⚠️ 优先级说明(必背):如果Cache-Control和Expires同时存在,Cache-Control 优先级 > Expires(因为Expires的缺陷太明显,现在基本用Cache-Control)。

📌 强缓存流程图(面试口述必背)

  1. 第一次请求:浏览器向服务器发送请求,服务器返回资源 + 强缓存控制字段(如Cache-Control: max-age=3600)

  2. 第二次请求(1小时内,未过期):浏览器检查本地缓存,发现资源未过期

  3. 直接从本地缓存读取资源,不向服务器发送任何请求

🎯 面试示例(帮助理解,可背诵)

场景:你的网站有一个脚本文件 <script src="app.js"></script>,服务器返回的响应头包含 Cache-Control: max-age=600(10分钟)。

结果:10分钟内刷新页面,Network面板会显示 app.js 的状态为 from memory cache,且没有任何HTTP请求发送到服务器。

三、协商缓存(Conditional Cache)------ 面试高频重点

✅ 核心特点(必背)

通俗说:强缓存过期了,浏览器不确定资源有没有更新,就向服务器"请示",由服务器判断要不要用本地缓存。

专业表述:浏览器会发送HTTP请求到服务器,服务器对比资源状态,决定是否复用本地缓存;若资源未变化,服务器返回状态码 304 Not Modified(不返回资源内容,只返回响应头);若资源已变化,返回200 + 新资源。

协商缓存的两种实现方式(必背,面试常考对比)

1️⃣ Last-Modified + If-Modified-Since(基于时间的判断,较老旧)

通俗说:服务器记录资源最后修改时间,浏览器下次请求时,带上这个时间,服务器对比"现在的修改时间"和"浏览器带的时间",判断资源有没有变。

  1. 第一次请求:服务器返回资源,并在响应头中添加 Last-Modified(资源最后修改时间),示例: Last-Modified: Wed, 01 Mar 2026 10:00:00 GMT

  2. 第二次请求:浏览器读取本地缓存中的 Last-Modified,在请求头中添加 If-Modified-Since(带上上次的修改时间),示例: If-Modified-Since: Wed, 01 Mar 2026 10:00:00 GMT

  3. 服务器判断:

    • 资源未修改(当前修改时间 = If-Modified-Since)→ 返回 304,浏览器用本地缓存

    • 资源已修改(当前修改时间 > If-Modified-Since)→ 返回 200 + 新资源 + 新的 Last-Modified

❌ 缺点(必背,面试常考)
  • 时间精度低:只能精确到秒,若1秒内资源被修改多次,服务器无法识别

  • 误判风险:文件修改但内容未变(如修改文件名再改回),服务器会认为资源已修改,返回新资源(浪费流量)

2️⃣ ETag + If-None-Match(基于内容的判断,更精准,面试重点)

通俗说:服务器给资源生成一个"内容指纹"(比如根据文件内容计算的一串字符),浏览器下次请求时带上这个指纹,服务器对比当前资源的指纹和浏览器带的指纹,判断内容有没有变。

  1. 第一次请求:服务器返回资源,并在响应头中添加 ETag(资源内容指纹),示例: ETag: "abc123"

  2. 第二次请求:浏览器读取本地缓存中的 ETag,在请求头中添加 If-None-Match(带上上次的指纹),示例: If-None-Match: "abc123"

  3. 服务器判断:

    • 指纹一致(资源内容未变)→ 返回 304,浏览器用本地缓存

    • 指纹不一致(资源内容已变)→ 返回 200 + 新资源 + 新的 ETag

📌 优先级(必背)

ETag > Last-Modified(因为ETag基于内容判断,更精准,能解决Last-Modified的缺点)。

四、强缓存 vs 协商缓存(面试必背对比,建议默写)

对比维度 强缓存 协商缓存
是否发送HTTP请求 ❌ 不发送 ✅ 发送(仅验证,不传递资源内容)
返回状态码 200 (from disk/memory cache) 304(未修改)/ 200(已修改)
服务器是否参与判断 否(浏览器自主判断) 是(服务器判断资源状态)
性能 更好(无需请求服务器) 次之(需发送请求,无需传输资源)

五、完整缓存流程(面试必会,口述核心)

浏览器请求资源时,判断顺序如下(必背,面试口述要流畅):

  1. 1️⃣ 先判断是否有强缓存:

    • 有强缓存,且资源未过期 → 直接读取本地缓存,不发送请求

    • 有强缓存,但资源已过期 → 进入协商缓存流程

  2. 2️⃣ 再判断是否有协商缓存标识(Last-Modified/ETag):

    • 有标识 → 发送请求到服务器,验证资源是否变化

    • 资源未修改 → 服务器返回304,浏览器用本地缓存

    • 资源已修改 → 服务器返回200 + 新资源,更新本地缓存

  3. 3️⃣ 既没有强缓存,也没有协商缓存 → 正常发送请求,服务器返回200 + 资源,同时设置缓存标识(强/协商)

六、真实场景应用(面试加分项,必背)

🎯 场景1:JS/CSS等静态文件更新了,如何保证用户拿到新版本?

通俗说:给静态文件名加"指纹"(hash值),比如 app.js 改成 app.1a2b3c.js,这样更新后文件名变了,浏览器会认为是新资源,重新下载。

专业表述:采用「缓存破坏(Cache Busting)」策略,具体操作:

  • 给静态资源(JS、CSS、图片)文件名添加hash后缀(如app.hash.js)

  • 给静态资源设置强缓存,max-age=31536000(一年,因为文件名变了才会更新,不用担心过期)

  • 资源更新时,hash值会变化,文件名随之改变,浏览器会识别为新资源,重新请求下载

🎯 场景2:用户强制刷新页面,缓存会发生什么变化?(面试常考)

  • 普通刷新(点击刷新按钮/按F5):正常走缓存逻辑(先强缓存,再协商缓存)

  • 强制刷新(Ctrl + F5):跳过强缓存,直接进入协商缓存(相当于给请求头添加 Cache-Control: no-cache)

  • DevTools勾选 Disable cache:完全不使用任何缓存,每次请求都从服务器获取新资源

七、面试高频问题(必背,直接记答案)

❓1. 为什么需要协商缓存?

核心答案:强缓存过期后,资源可能并没有发生变化,如果直接重新下载会浪费流量和时间;协商缓存可以通过服务器验证资源状态,未变化则复用本地缓存,既保证资源新鲜,又提升性能、节省带宽。

❓2. 304状态码会返回资源内容吗?为什么?

核心答案:不会。因为304是"资源未修改"的响应,服务器只需告诉浏览器"可以用本地缓存"即可,无需返回资源内容,这样能减少网络传输量,提升加载速度。

❓3. 强缓存一般设置多久?不同资源有区别吗?

核心答案:有区别,分资源类型设置:

  • HTML文件:不设置强缓存,或设置协商缓存(因为HTML是入口文件,若强缓存,会导致引用的静态资源更新后,用户仍读取旧HTML,无法获取新版本)

  • 静态资源(JS、CSS、图片,带hash):设置1年(max-age=31536000),因为文件名带hash,更新时会自动触发缓存更新,无需担心过期问题。

❓4. 为什么HTML文件不能设置强缓存?(延伸题,必背)

核心答案:HTML是页面入口文件,负责引用JS、CSS等静态资源。如果给HTML设置强缓存,当静态资源更新(文件名变了),但HTML仍处于强缓存有效期内,浏览器会直接读取旧HTML,引用的还是旧的静态资源路径,导致用户无法看到新版本的页面。

❓5. no-cache 和 no-store 的区别?(高频易错,必背)

核心答案:两者都禁止强缓存,但对协商缓存和本地存储的处理不同:

  • no-cache:允许本地缓存,但不允许直接使用强缓存,必须发送请求到服务器进行协商缓存验证,验证通过后才能使用本地缓存。

  • no-store:完全禁止本地缓存,不允许浏览器存储任何资源,每次请求都必须从服务器获取完整资源,不存在缓存复用。

❓6. 浏览器缓存失效的场景有哪些?(面试加分)

核心答案:4种常见场景:

  • 用户手动清除浏览器缓存(如设置中清除浏览数据)

  • 用户进行强制刷新(Ctrl + F5)

  • 服务器修改了缓存控制字段(如修改Cache-Control、ETag、Last-Modified)

  • 静态资源文件名发生变化(如hash值改变,触发缓存破坏)

八、面试标准回答模板(必背,直接套用)

当面试官问:"请讲一下浏览器缓存机制?",按以下结构回答(流畅、有条理,加分):

  1. 浏览器缓存主要分为强缓存和协商缓存,两者合称HTTP缓存,是面试重点;还有一种Service Worker缓存,属于可编程缓存,非重点。

  2. 强缓存的核心是"不发请求,直接用缓存",由Cache-Control和Expires控制,其中Cache-Control优先级更高,常用指令有max-age、no-cache、no-store等,未过期时返回200 (from disk/memory cache)。

  3. 协商缓存的核心是"发请求,服务器决定是否用缓存",有两种实现方式:ETag+If-None-Match(基于内容,更精准)和Last-Modified+If-Modified-Since(基于时间,有缺陷),ETag优先级更高,未修改返回304,已修改返回200。

  4. 完整请求流程:先判断强缓存,未过期直接用;过期则进入协商缓存,服务器验证资源状态,未修改用缓存,已修改下载新资源;两者都没有则正常请求。

  5. 生产环境应用:静态资源(带hash)设1年强缓存,通过文件名hash实现缓存破坏;HTML不做强缓存,避免引用旧资源。

🔥 总结一句话(面试收尾,加深印象)

浏览器请求资源时,优先走强缓存,不发请求、直接复用本地资源;强缓存过期后走协商缓存,通过ETag或Last-Modified向服务器验证资源状态,未变化返回304复用缓存,已变化返回200获取新资源,最终实现"高效加载、节省带宽"的目的。

相关推荐
mldong1 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排2 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60612 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角3 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰4 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
Interview Aid1124 小时前
Walmart Global Tech SDE 三轮面经|基础、并发、压力面
面试·职场和发展
mayaairi5 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen6 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马7 小时前
AI源码分析:拆解模型底层实现逻辑
前端