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

相关推荐
guicai_guojia2 分钟前
面试题篇: 跨域问题如何处理(Java和Nginx处理方式)
java·开发语言·nginx
coderWangbuer2 分钟前
基于springboot的二手物品管理系统的设计与实现 (含源码+sql+视频导入教程)
spring boot·后端·sql
Amagi.3 分钟前
对比介绍Java Servlet API (javax.servlet)和Apache HttpClient这两个库
java·servlet·apache
蜘蛛news30 分钟前
快手怎么关闭ip地址 抖音ip属地如何隐藏
网络·网络协议·tcp/ip
lzb_kkk1 小时前
【Redis】redis5种数据类型(哈希)
开发语言·redis·算法·缓存·哈希算法
易雪寒1 小时前
Maven从入门到精通(二)
java·maven
ersaijun1 小时前
【Obsidian】当笔记接入AI,Copilot插件推荐
人工智能·笔记·copilot
我叫于豆豆吖1 小时前
绕过CDN查找真实IP方法
网络·网络协议·tcp/ip
易雪寒2 小时前
Maven从入门到精通(三)
java·python·maven
AskHarries2 小时前
maven父子工程多模块如何管理统一的版本号?
java·spring boot·后端·maven