前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

# HTTP的缓存代理

30 秒速记

  • 缓存不只在浏览器,链路中间的代理也能存,请求「就近」拿到结果
  • 代理命中后请求根本到不了源站,应用、数据库都不用动
  • 最适合读多写少、瞬间高并发的内容:热点新闻、爆款详情页
  • 哪怕只缓存几秒,源站 RPS 也能降几个数量级
  • Redis、Memcache 这类应用内缓存是另一回事:请求照样要进应用

缓存代理就是把响应存在源站前面的那一层,后来的请求在半路就被打发了。 比如爆款商品页一秒一万次请求,源站生成一次要 80ms,代理缓存 5 秒,那这 5 秒里只有第一个请求回源,剩下全在代理层返回,源站基本没压力。它和 Redis 的区别在于拦截的位置:Redis 命中了,请求还是要进 Node / Java 进程走一遍逻辑;代理命中,请求连应用的门都没进。两者可以叠着用,但指标要分开看。

之前谈到缓存时,主要讲了客户端(浏览器)上的缓存控制,它能够减少响应时间、节约带宽,提升客户端的用户体验。

但 HTTP 传输链路上,不只是客户端有缓存,服务器上的缓存也是非常有价值的,可以让请求不必走完整个后续处理流程,“就近”获得响应结果。

特别是对于那些“读多写少”的数据,例如突发热点新闻、爆款商品的详情页,一秒钟内可能有成千上万次的请求。即使仅仅缓存数秒钟,也能够把巨大的访问流量挡在外面,让 RPS(request per second)降低好几个数量级,减轻应用服务器的并发压力,对性能的改善是非常显著的。

HTTP 的服务器缓存功能主要由代理服务器来实现(即缓存代理),而源服务器系统内部虽然也经常有各种缓存(如 Memcache、Redis、Varnish 等),但与 HTTP 没有太多关系,所以这里暂且不说

原理拆解: 缓存代理位于客户端与源站之间。首次请求未命中时,代理向源站取回响应,根据请求方法、状态码和缓存控制字段判断是否保存;后续请求若缓存键相同且响应仍新鲜,代理直接返回副本,应用、数据库等源站链路都不会被触发。假设源站生成商品页需要 80ms,代理缓存 5s,这段时间内到达的数千次请求便可能只产生一次回源。

最小验证: 输入是两个连续的同资源请求,验证第二次响应可由共享代理复用,并通过 Age 观察缓存对象已经存活的时间。

GET /products/42 HTTP/1.1
Host: shop.example
Accept: application/json

HTTP/1.1 200 OK
Cache-Control: public, max-age=5
Content-Type: application/json
Content-Length: 25

{"id":42,"stock":"many"}

GET /products/42 HTTP/1.1
Host: shop.example
Accept: application/json

HTTP/1.1 200 OK
Cache-Control: public, max-age=5
Age: 2
Content-Type: application/json
Content-Length: 25

{"id":42,"stock":"many"}
@前端进阶之旅: 代码已经复制到剪贴板

第二个响应中的 Age: 2 表示共享缓存持有该响应约两秒;是否命中还可结合代理访问日志中的 HIT 标记确认。压测时应同时比较代理入口 RPS 与源站 RPS,命中生效后前者可保持高位,而后者明显下降。

边界与排查: 缓存键通常至少包含请求目标,并受 Vary 指定的请求头影响;不同编码、语言或鉴权上下文不能错误复用。写操作、强个性化页面和实时库存不宜仅靠固定时长缓存。Redis 缓存仍需应用接收请求并执行取值逻辑,而 HTTP 代理命中会在源站之前终止链路,两者可以叠加,但监控指标和失效策略不能混为一谈。

面试官追问

追问 1接口已经有 Redis 缓存了,再加一层代理缓存是不是重复?
参考回答

不重复。Redis 省的是数据库,代理缓存省的是整个应用层,连接数、CPU、序列化都省了。热点流量真打上来时,应用实例先扛不住的往往是请求数本身。

追问 2怎么确认代理缓存真的生效了,不是自己感觉变快?
参考回答

看第二次响应的 Age 头有没有值,以及代理日志里的 HIT / MISS。最硬的证据是对比代理入口 RPS 和源站 RPS,命中生效时前者高、后者明显降下来。

追问 3新闻页缓存 10 秒,编辑改了错别字要求立刻生效,怎么办?
参考回答

两条路:缩短缓存时间,或者发布时调代理的 PURGE 接口主动删缓存。真要求零延迟就得接受更多回源,固定时长缓存天生会有一段旧数据窗口。

追问 4接口按 Accept-Language 返回不同语言,代理只按 URL 缓存会怎样?
参考回答

中文用户可能拿到英文页面。源站要返回 Vary: Accept-Language,让代理把语言也算进缓存键。代价是同一个 URL 拆成多份,命中率会下降,语言多的话可以先把头归一化成几种。

# 缓存代理服务

30 秒速记

  • 没缓存的代理只转发;有缓存的代理拿到响应后做两件事:转给客户端 + 存一份
  • 新鲜期内命中:代理直接回 200 + 完整内容,不找源站
  • 过期了:代理带 If-None-Match 去问源站,源站回 304,代理再用本地副本给客户端拼一个 200
  • 命中 ≠ 304:304 只在请求方自己带了条件头时才会回给它
  • 代理既是客户端又是服务器,所以两边的 Cache-Control 都管它,另外还有几条专门约束共享缓存的指令

缓存代理就是给便利店配了个冰柜,进一次货能卖很多次。 第一次请求没命中,代理去源站拿,拿到后一边转给用户一边存起来;之后同样的请求,副本还新鲜就直接回 200。过期了也不用重下,代理自己拿 ETag 去源站做条件请求,源站说 304 没变,代理刷新一下有效期,再用存着的内容给用户回完整的 200。很多人以为缓存命中就是 304,其实用户看到 304 只有一种情况:浏览器自己也发了条件请求。

我还是沿用“生鲜速递 + 便利店”的比喻,看看缓存代理是怎么回事。

便利店作为超市的代理,生意非常红火,顾客和超市双方都对现状非常满意。但时间一长,超市发现还有进一步提升的空间,因为每次便利店接到顾客的请求后都要专车跑一趟超市,还是挺麻烦的。

干脆这样吧,给便利店配发一个大冰柜。水果海鲜什么的都可以放在冰柜里,只要产品在保鲜期内,就允许顾客直接从冰柜提货。这样便利店就可以一次进货多次出货,省去了超市之间的运输成本。

通过这个比喻,你可以看到:在没有缓存的时候,代理服务器每次都是直接转发客户端和服务器的报文,中间不会存储任何数据,只有最简单的中转功能。

加入了缓存后就不一样了。

代理服务收到源服务器发来的响应数据后需要做两件事。第一个当然是把报文转发给客户端,而第二个就是把报文存入自己的 Cache 里。

下一次再有相同的请求,代理服务器就可以直接发送 304 或者缓存数据,不必再从源服务器那里获取。这样就降低了客户端的等待时间,同时节约了源服务器的网络带宽。

在 HTTP 的缓存体系中,缓存代理的身份十分特殊,它“既是客户端,又是服务器”,同时也“既不是客户端,又不是服务器”。

说它“即是客户端又是服务器”,是因为它面向源服务器时是客户端,在面向客户端时又是服务器,所以它即可以用客户端的缓存控制策略也可以用服务器端的缓存控制策略,也就是说它可以同时使用第 20 讲的各种“Cache-Control”属性。

但缓存代理也“即不是客户端又不是服务器”,因为它只是一个数据的“中转站”,并不是真正的数据消费者和生产者,所以还需要有一些新的“Cache-Control”属性来对它做特别的约束

原理拆解: 普通代理对每次请求都建立上游交互;缓存代理则在转发首次响应时保存响应头、响应体及存储时间。再次收到等价请求后,它先计算当前年龄和新鲜度:仍新鲜便直接返回 200 与缓存实体;已经过期且存在验证器时,代理向源站发送条件请求,源站返回 304 后,代理更新元数据并把可用实体返回给客户端。

最小验证: 输入是代理对过期对象进行再验证的完整报文,验证 304 发生在代理与源站之间,而客户端最终仍可收到带响应体的 200。

GET /news/hot HTTP/1.1
Host: origin.example
If-None-Match: "news-v7"

HTTP/1.1 304 Not Modified
Date: Mon, 17 Aug 2026 02:00:10 GMT
ETag: "news-v7"
Cache-Control: public, max-age=10

HTTP/1.1 200 OK
Date: Mon, 17 Aug 2026 02:00:10 GMT
Age: 0
ETag: "news-v7"
Cache-Control: public, max-age=10
Content-Type: application/json
Content-Length: 24

{"title":"hot","rev":7}
@前端进阶之旅: 代码已经复制到剪贴板

前两段是代理作为客户端向源站验证及获得 304;最后一段是代理作为服务器,用本地实体组装给下游的响应。若下游自己发送了条件请求且验证条件成立,代理也可能直接向下游返回不含实体的 304,但不能把“缓存命中”一概等同于 304。

边界与排查: POST、带认证信息的请求或含 no-store 的响应通常不能按普通公开资源复用;Vary 还会把指定请求头纳入匹配条件。工程验证应记录 HIT、MISS、STALE、回源次数和

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
        • 缓存代理服务
        • 源服务器的缓存控制
        • 客户端的缓存控制
        • 小结
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

HTTP的缓存代理|HTTP协议篇

# HTTP的缓存代理

30 秒速记

  • 缓存不只在浏览器,链路中间的代理也能存,请求「就近」拿到结果
  • 代理命中后请求根本到不了源站,应用、数据库都不用动
  • 最适合读多写少、瞬间高并发的内容:热点新闻、爆款详情页
  • 哪怕只缓存几秒,源站 RPS 也能降几个数量级
  • Redis、Memcache 这类应用内缓存是另一回事:请求照样要进应用

缓存代理就是把响应存在源站前面的那一层,后来的请求在半路就被打发了。 比如爆款商品页一秒一万次请求,源站生成一次要 80ms,代理缓存 5 秒,那这 5 秒里只有第一个请求回源,剩下全在代理层返回,源站基本没压力。它和 Redis 的区别在于拦截的位置:Redis 命中了,请求还是要进 Node / Java 进程走一遍逻辑;代理命中,请求连应用的门都没进。两者可以叠着用,但指标要分开看。

之前谈到缓存时,主要讲了客户端(浏览器)上的缓存控制,它能够减少响应时间、节约带宽,提升客户端的用户体验。

但 HTTP 传输链路上,不只是客户端有缓存,服务器上的缓存也是非常有价值的,可以让请求不必走完整个后续处理流程,“就近”获得响应结果。

特别是对于那些“读多写少”的数据,例如突发热点新闻、爆款商品的详情页,一秒钟内可能有成千上万次的请求。即使仅仅缓存数秒钟,也能够把巨大的访问流量挡在外面,让 RPS(request per second)降低好几个数量级,减轻应用服务器的并发压力,对性能的改善是非常显著的。

HTTP 的服务器缓存功能主要由代理服务器来实现(即缓存代理),而源服务器系统内部虽然也经常有各种缓存(如 Memcache、Redis、Varnish 等),但与 HTTP 没有太多关系,所以这里暂且不说

原理拆解: 缓存代理位于客户端与源站之间。首次请求未命中时,代理向源站取回响应,根据请求方法、状态码和缓存控制字段判断是否保存;后续请求若缓存键相同且响应仍新鲜,代理直接返回副本,应用、数据库等源站链路都不会被触发。假设源站生成商品页需要 80ms,代理缓存 5s,这段时间内到达的数千次请求便可能只产生一次回源。

最小验证: 输入是两个连续的同资源请求,验证第二次响应可由共享代理复用,并通过 Age 观察缓存对象已经存活的时间。

GET /products/42 HTTP/1.1
Host: shop.example
Accept: application/json

HTTP/1.1 200 OK
Cache-Control: public, max-age=5
Content-Type: application/json
Content-Length: 25

{"id":42,"stock":"many"}

GET /products/42 HTTP/1.1
Host: shop.example
Accept: application/json

HTTP/1.1 200 OK
Cache-Control: public, max-age=5
Age: 2
Content-Type: application/json
Content-Length: 25

{"id":42,"stock":"many"}
@前端进阶之旅: 代码已经复制到剪贴板

第二个响应中的 Age: 2 表示共享缓存持有该响应约两秒;是否命中还可结合代理访问日志中的 HIT 标记确认。压测时应同时比较代理入口 RPS 与源站 RPS,命中生效后前者可保持高位,而后者明显下降。

边界与排查: 缓存键通常至少包含请求目标,并受 Vary 指定的请求头影响;不同编码、语言或鉴权上下文不能错误复用。写操作、强个性化页面和实时库存不宜仅靠固定时长缓存。Redis 缓存仍需应用接收请求并执行取值逻辑,而 HTTP 代理命中会在源站之前终止链路,两者可以叠加,但监控指标和失效策略不能混为一谈。

面试官追问

追问 1接口已经有 Redis 缓存了,再加一层代理缓存是不是重复?
参考回答

不重复。Redis 省的是数据库,代理缓存省的是整个应用层,连接数、CPU、序列化都省了。热点流量真打上来时,应用实例先扛不住的往往是请求数本身。

追问 2怎么确认代理缓存真的生效了,不是自己感觉变快?
参考回答

看第二次响应的 Age 头有没有值,以及代理日志里的 HIT / MISS。最硬的证据是对比代理入口 RPS 和源站 RPS,命中生效时前者高、后者明显降下来。

追问 3新闻页缓存 10 秒,编辑改了错别字要求立刻生效,怎么办?
参考回答

两条路:缩短缓存时间,或者发布时调代理的 PURGE 接口主动删缓存。真要求零延迟就得接受更多回源,固定时长缓存天生会有一段旧数据窗口。

追问 4接口按 Accept-Language 返回不同语言,代理只按 URL 缓存会怎样?
参考回答

中文用户可能拿到英文页面。源站要返回 Vary: Accept-Language,让代理把语言也算进缓存键。代价是同一个 URL 拆成多份,命中率会下降,语言多的话可以先把头归一化成几种。

# 缓存代理服务

30 秒速记

  • 没缓存的代理只转发;有缓存的代理拿到响应后做两件事:转给客户端 + 存一份
  • 新鲜期内命中:代理直接回 200 + 完整内容,不找源站
  • 过期了:代理带 If-None-Match 去问源站,源站回 304,代理再用本地副本给客户端拼一个 200
  • 命中 ≠ 304:304 只在请求方自己带了条件头时才会回给它
  • 代理既是客户端又是服务器,所以两边的 Cache-Control 都管它,另外还有几条专门约束共享缓存的指令

缓存代理就是给便利店配了个冰柜,进一次货能卖很多次。 第一次请求没命中,代理去源站拿,拿到后一边转给用户一边存起来;之后同样的请求,副本还新鲜就直接回 200。过期了也不用重下,代理自己拿 ETag 去源站做条件请求,源站说 304 没变,代理刷新一下有效期,再用存着的内容给用户回完整的 200。很多人以为缓存命中就是 304,其实用户看到 304 只有一种情况:浏览器自己也发了条件请求。

我还是沿用“生鲜速递 + 便利店”的比喻,看看缓存代理是怎么回事。

便利店作为超市的代理,生意非常红火,顾客和超市双方都对现状非常满意。但时间一长,超市发现还有进一步提升的空间,因为每次便利店接到顾客的请求后都要专车跑一趟超市,还是挺麻烦的。

干脆这样吧,给便利店配发一个大冰柜。水果海鲜什么的都可以放在冰柜里,只要产品在保鲜期内,就允许顾客直接从冰柜提货。这样便利店就可以一次进货多次出货,省去了超市之间的运输成本。

通过这个比喻,你可以看到:在没有缓存的时候,代理服务器每次都是直接转发客户端和服务器的报文,中间不会存储任何数据,只有最简单的中转功能。

加入了缓存后就不一样了。

代理服务收到源服务器发来的响应数据后需要做两件事。第一个当然是把报文转发给客户端,而第二个就是把报文存入自己的 Cache 里。

下一次再有相同的请求,代理服务器就可以直接发送 304 或者缓存数据,不必再从源服务器那里获取。这样就降低了客户端的等待时间,同时节约了源服务器的网络带宽。

在 HTTP 的缓存体系中,缓存代理的身份十分特殊,它“既是客户端,又是服务器”,同时也“既不是客户端,又不是服务器”。

说它“即是客户端又是服务器”,是因为它面向源服务器时是客户端,在面向客户端时又是服务器,所以它即可以用客户端的缓存控制策略也可以用服务器端的缓存控制策略,也就是说它可以同时使用第 20 讲的各种“Cache-Control”属性。

但缓存代理也“即不是客户端又不是服务器”,因为它只是一个数据的“中转站”,并不是真正的数据消费者和生产者,所以还需要有一些新的“Cache-Control”属性来对它做特别的约束

原理拆解: 普通代理对每次请求都建立上游交互;缓存代理则在转发首次响应时保存响应头、响应体及存储时间。再次收到等价请求后,它先计算当前年龄和新鲜度:仍新鲜便直接返回 200 与缓存实体;已经过期且存在验证器时,代理向源站发送条件请求,源站返回 304 后,代理更新元数据并把可用实体返回给客户端。

最小验证: 输入是代理对过期对象进行再验证的完整报文,验证 304 发生在代理与源站之间,而客户端最终仍可收到带响应体的 200。

GET /news/hot HTTP/1.1
Host: origin.example
If-None-Match: "news-v7"

HTTP/1.1 304 Not Modified
Date: Mon, 17 Aug 2026 02:00:10 GMT
ETag: "news-v7"
Cache-Control: public, max-age=10

HTTP/1.1 200 OK
Date: Mon, 17 Aug 2026 02:00:10 GMT
Age: 0
ETag: "news-v7"
Cache-Control: public, max-age=10
Content-Type: application/json
Content-Length: 24

{"title":"hot","rev":7}
@前端进阶之旅: 代码已经复制到剪贴板

前两段是代理作为客户端向源站验证及获得 304;最后一段是代理作为服务器,用本地实体组装给下游的响应。若下游自己发送了条件请求且验证条件成立,代理也可能直接向下游返回不含实体的 304,但不能把“缓存命中”一概等同于 304。

边界与排查: POST、带认证信息的请求或含 no-store 的响应通常不能按普通公开资源复用;Vary 还会把指定请求头纳入匹配条件。工程验证应记录 HIT、MISS、STALE、回源次数和 Age,并同时检查源站日志。只有客户端耗时下降而源站请求数未下降,常见原因是缓存键碎片化、有效期过短,或响应根本不可缓存。

面试官追问

追问 1静态资源走代理后变快了,有人记录成「命中缓存返回 304」,哪里不对?
参考回答

新鲜命中时代理回的是带内容的 200,不是 304。304 是验证结果,而且没有响应体,只有请求方自己带了 If-None-Match 这类头才会收到。

追问 2源站给代理回了 304,代理能把这个 304 原样转给普通浏览器吗?
参考回答

不能。浏览器没发条件请求,它手里也没有副本,收到空的 304 没法用。代理要拿自己存的内容拼一个完整的 200 给它。

追问 3代理日志一直是 MISS,可每次响应看起来都一样,按什么顺序查?
参考回答

先看响应能不能被共享缓存存:有没有 private、no-store、Set-Cookie。再看缓存键是不是每次都变,比如 URL 上挂了时间戳参数,或者 Vary: User-Agent 把键切得太碎。最后看 max-age 是不是短到刚存进去就过期了。

追问 4账户页带登录态,能不能也让代理缓存一下减压?
参考回答

一般我会直接拦。一旦缓存键漏掉了用户身份,A 的页面就会发给 B,这是隐私事故。响应要标 Cache-Control: private,真要加速就把页面里公共的部分拆出来单独缓存。

# 源服务器的缓存控制

← HTTP的代理服务对称加密与非对称加密 →

fe