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等缓存机制,可以极大提升用户体验和服务器性能。

相关推荐
m0_5719575829 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
龙鸣丿34 分钟前
Linux基础学习笔记
linux·笔记·学习
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Nu11PointerException3 小时前
JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习
笔记·学习
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
Chrikk4 小时前
Go-性能调优实战案例
开发语言·后端·golang
亦枫Leonlew4 小时前
三维测量与建模笔记 - 3.3 张正友标定法
笔记·相机标定·三维重建·张正友标定法
幼儿园老大*4 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue4 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang