反骨仔

一个业余的 .NET Core 攻城狮

0%

06 HTTP 协议中的缓存

了解这些缓存机制对提高网站的性能非常有帮助。

6.1 缓存的概念

HTTP 中具有缓存功能的是浏览器缓存和代理服务器缓存。

HTTP 缓存是指当 Web 请求抵达缓存时,如果本地有“己缓存 的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档 。

6.2 缓存的优点

缓存的好处:

  1. 减少了冗余的数据传输,节省了传输时间
  2. 减少了服务器的负担,可以让服务器去处理更多请求
  3. 加快了客户端加载网页的速度

6.3 Fiddle 可以方便地查看缓存的 Header

Fiddler 中的 Header 选项卡已经把 Header 进行分类摆放,把跟 Cache 相关的 Header 放在一起,这样方便查看。

image-20210103030537853

6.4 如何判断缓存新鲜度

Web 服务器通过以下 2 种方式来判断浏览器缓存是否最新:

  1. 浏览器把缓存文件的最后修改时间通过 Header “ If-Modified-Since"告诉 Web 服务器
  2. 浏览器把缓存文件的 ETag 通过 Header “ If-None-Match "告诉 Web 服务器

6.5 通过最后修改时间来判断缓存新鲜度

浏览器可以通过缓存文件的修改时间来判断缓存的新鲜度 。

  1. 如果浏览器客户端想请求一个文档,它首先检查本地缓存 ,发现存在这个文档的缓存,获取缓存中文档的最后修改时间,通过“ If-Modified -Since "发送 HTTP 请求给 Web 服务器

  2. Web 服务器收到 HTTP 请求,将服务器的文档修改时间( Last-Modified )跟 HTTP 请求 Header 中的 If-Modified-Since 相比较。如果时间是一样的,说明缓存还是最新的,Web 服务器将发送状态码 304 (Not Modified ) 给浏览器客户端,告诉客户端直接使用缓存里的版本

image-20210103030840728

  1. 假如该文档己经被更新了,Web 服务器将发送该文档的最新版本给浏览器客户端

image-20210103030904507

【实例】启动 Fiddler,然后打开博客园首页 。 按快捷键【F5】刷新几次浏览器,会看到博客园首页也用了缓存 。

image-20210103031024349

6.6 与缓存有关的 Header

image-20210103031052930

image-20210103031125096

如果同时存在 cache-control 和 Expires 怎么办呢?

  • 浏览器总是优先使用 cache-control
  • 如果没有 cache-control 才考虑 Expires

6.7 ETag

ETag 是 Entity Tag(实体标签)的缩写,是根据实体内容生成的一段 hash 字符串(类似于 MD5 或者 SHA1 之后的结果),可以标识资源的状态。当资源发生改变时,ETag 也随之发生变化。

ETag 是 Web 服务端产生的,然后发给浏览器客户端。浏览器客户端不用关心 ETag 是如何产生的。

使用 ETag 主要是为了解决一些 Last-Modified 无法解决的问题。

  1. 某些服务器不能精确得到文件的最后修改时间,这样就无法通过最后修改时间来判断文件是否更新了
  2. 某些文件的修改非常频繁,在以秒为单位以下的时间内进行修改,而 Last-Modified 只能精确到秒
  3. 一些文件的最后修改时间改变了,但是内容并未改变,我们不希望客户端认为这个文件修改了

【实例】启动 Fiddler,然后打开博客园首页。可以看到很多图片或者 css 文件都使用了缓存。这些都是通过比较 ETag 的值来判断文件是否更新了。

image-20210103031539301

6.8 浏览器不使用缓存

使用【Ctrl+F5】快捷键强制刷新浏览器,可以让浏览器不使用缓存:

  1. 浏览器发送 HTTP 请求给 Web 服务器,Header 中带有 Cache-Control: no-cache,明确告诉 Web 服务器客户端不使用缓存
  2. Web 服务器将把最新的文档发送给浏览器客户端

【实例】启动 Fiddler,打开博客园首页,然后按【Ctr l+F5】快捷键强制刷新浏览器。你将看到浏览器发送的 HTTP 请求中有“ Cache-Control:no-cache ”

  • “Pragma: no-cache"的作用和“ Cache-Control: no-cache”一模一样,都是不使用缓存
  • “Pragma: no-cache ”是 HTTP 1.0 中定义的,所以为了兼容 HTTP 1.0 会同时使用“ Pragma:no-cache ”和“ Cache-Control: no-cache ”

image-20210103031850336

6.9 直接使用缓存,不去服务器验证

按【F5】快捷键刷新浏览器并在地址栏里输入网址,然后按回车键,这两个行为是不一样的。

按【F5】快捷键刷新浏览器,浏览器会去 Web 服务器验证缓存。

如果是在地址栏输入网址然后按回车键,浏览器会“直接使用有效的缓存”,而不会发送 HTTP 请求去服务器验证缓存,这种情况叫作缓存命中。

image-20210103032130483

【实例】比较第一次访问博客园主页和第二次访问博客园主页

  1. 启动 Fiddler,打开 Firefox,打开博客园主页 hhttp://www.cnblogs.com,发现有 50 多个 Session
  2. 按【Ctrl+X】快捷键将 Fiddler 中的所有 Session 删除
  3. 关闭 Firefox 后,然后再次打开博客园主页,可以看到只有 30 多个 Session。

【分析】少了很多 Session 是因为 Firefox 直接使用了缓存,而没有发送 HTTP 请求。

image-20210103032453779

6.10 如何设置 IE 不使用缓存

打开 IE ,单击工具栏上的工具 -> Internet 选项 -> 常规 -> 浏览历史记录 -> 设置,选择“从不”,然后保存,可以让浏览器不使用缓存。

单击“删除”,可以把 Internet 临时文件都删掉(IE 缓存的文件就是 Internet 临时文件)。

缓存文件都保存在一个文件夹下,这个文件夹可以这样找到:打开 IE,单击工具栏上的工具 -> Internet 选项 -> 常规 -> 浏览历史记录 -> 设置 -> 查看文件。

image-20210103032730799

6.11 公布缓存和私有缓存的区别

“ Cache-Control:public ”指可 以公有缓存 ,缓存可以由数千名用户共享。“ Cache-Control:private " 指只支持私有缓存,私有缓存是单个用户专用的。

image-20210103032848554

参考

  • 《HTTP 抓包实战》