Java 面试题:HTTP缓存:强制缓存和协商缓存--xunznux

文章目录

以下是整理后的关于HTTP缓存的内容,修正了错误并补充了缺失的知识点:

HTTP缓存

HTTP缓存是一种在客户端或代理服务器本地存储资源副本的机制,旨在提高访问效率和减少带宽消耗。当客户端再次请求已经缓存的资源时,会优先检查本地缓存是否有效。如果存在有效缓存,直接使用本地缓存数据,而无需再次通过网络获取服务器的响应。这就是HTTP缓存的基本原理。

HTTP缓存主要有两种实现方式:强制缓存协商缓存

强制缓存

强制缓存是指浏览器判断请求的资源是否命中强缓存规则,如果命中,则直接从本地缓存读取资源,无需与服务器进行任何通讯。

  • Expires(已弃用) :这是HTTP/1.0的缓存机制,服务器通过Expires头部指定资源过期时间。浏览器通过比较本地时间与Expires指定的时间来判断缓存是否有效。然而,由于Expires依赖客户端的本地时间,如果客户端的时间不准确,可能导致缓存判断出错。正因为如此,Expires在现代浏览器中已经基本被废弃,取而代之的是Cache-Control

  • Cache-Control :这是HTTP/1.1引入的更为精确的缓存控制机制,通过在Cache-Control头部指定缓存策略和过期时间,控制资源的缓存行为。Cache-Control支持多个指令,其中包括:

    • max-age=N:指定资源从请求时间开始缓存的最大有效时间(秒)。
    • s-maxage=N:专门针对共享缓存(如CDN),指定资源的缓存时间。
    • no-cache:不使用强制缓存,每次请求都必须向服务器进行验证(走协商缓存)。
    • no-store:禁止任何形式的缓存,资源每次都必须从服务器获取。
    • public:资源可以被浏览器和代理服务器缓存。
    • private:资源只能被浏览器缓存,不允许代理服务器缓存。

强制缓存的工作流程

  1. 浏览器首次请求资源时,服务器在响应中设置Cache-Control头部,并指定缓存策略。
  2. 浏览器在后续请求时,首先检查该资源是否命中强制缓存,如果未过期,则直接使用缓存,否则发起新的请求。
  3. 如果缓存过期,服务器将重新返回资源并更新Cache-Control头部。
协商缓存

当强制缓存失效或Cache-Control设置为no-cache时,浏览器会与服务器协商是否可以继续使用本地缓存,这种机制称为协商缓存。

  • Last-Modified 和 If-Modified-Since :通过资源的最后修改时间来判断缓存是否有效。
    1. 服务器在首次响应时,返回资源的最后修改时间,并通过Last-Modified头部传递给客户端。
    2. 客户端在后续请求时,通过If-Modified-Since头部携带上次获取的Last-Modified时间值。
    3. 服务器比较资源的最后修改时间和If-Modified-Since的时间,如果资源未修改,则返回304状态码,表示客户端可以使用本地缓存,否则返回新资源。

缺点

  • 因为基于修改时间判断,如果文件内容未改动但修改时间变动(如改名等),会导致不必要的缓存失效。

  • Last-Modified精度为秒,短时间内的多次修改可能导致缓存判断失误。

  • ETag 和 If-None-Match:使用资源的指纹(哈希值)判断缓存是否有效。

    1. 服务器在响应时为资源生成唯一的ETag(实体标签),并通过头部传递给客户端。
    2. 客户端在后续请求时,通过If-None-Match头部携带上次获取的ETag值。
    3. 服务器比较当前资源的ETagIf-None-Match的值,如果一致,则返回304状态码,表示缓存有效;否则返回新资源及更新后的ETag

优点

  • ETag更为精确,能捕捉到细微的内容变化,解决了Last-Modified可能忽略细微修改的问题。

缺点

  • 计算ETag需要一定的服务器资源,对于大型文件或高频访问场景,可能带来性能开销。
  • ETag支持强校验和弱校验,强校验基于每个字节的内容生成哈希值,虽然精确但计算量大;弱校验通过部分内容生成哈希值,计算速度快但可能降低准确性。

协商缓存的工作流程

  1. 当强制缓存未命中时,浏览器会根据上次响应的Last-ModifiedETag信息发起带有协商缓存字段的请求。
  2. 服务器根据客户端的If-Modified-SinceIf-None-Match进行缓存验证,并决定是否返回304状态码(缓存有效)或新的资源。

总结

HTTP缓存通过强制缓存和协商缓存两种方式,显著提高了资源访问的效率,减少了不必要的网络传输。在实际开发中,合理配置Cache-ControlETag等缓存机制,可以极大提升用户体验和服务器性能。

相关推荐
码路飞16 分钟前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
序安InToo19 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12319 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记21 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0522 分钟前
VS Code 配置 Markdown 环境
后端
navms25 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0525 分钟前
离线数仓的优化及重构
后端
Nyarlathotep011326 分钟前
gin01:初探gin的启动
后端·go
JxWang0527 分钟前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang0528 分钟前
Windows Terminal 配置 oh-my-posh
后端