【转载】掌握 HTTP 缓存——从请求到响应过程的一切(上)

简介: 作者:Ulrich Kautz 编译:胡子大哈翻译原文:http://huziketang.com/blog/posts/detail?postId=58b77935204d50674934c3ad 英文原文:Mastering HTTP Caching - from request to res...

作者:Ulrich Kautz 
编译:胡子大哈

翻译原文:http://huziketang.com/blog/posts/detail?postId=58b77935204d50674934c3ad 
英文原文:Mastering HTTP Caching - from request to response and everything

转载请注明出处,保留原文链接以及作者信息

学习笔记


HTPP 响应缓存头:

1、新版本指的是 HTTP/1.1

2、而旧版本指的是 HTTP/1.0

 

ETag:它是文档版本的标识符


 通常是内容的 MD5 值,不过它也可以包含其他内容,代表的是文档的版本/日期,如: 1.0 或者 2017-02-27。这里注意一点是,它必须用双引号括起来,如:ETag: "d3b07384d113edec49eaa6238ad5ff00"。

客户端请求了http://doc.tinywan.com:8038/cache2.txt,接着服务端返回了如下的响应内容:

第一次访问:

在响应里面,有两个有意思的头标识:

【1】一个是 ETag,内容的 MD5值。

【2】一个是 Last-Modified,这是 cache2.txt 文件最后一次被修改的时间。

这里就是二次验证起作用的地方:当客户端在很短的时间内再次访问上面的 URL,客户端浏览器会使用 If-* 请求头。如 If-None-Match 检查 ETag 的内容是否有改变。也就是说,如果 ETag 发生变化,客户端接收到的一个完整的新响应;如果 ETag 没变化,客户端接收到的是一个表明内容没变化的标识。

 第二次访问:

正如上面所展示的,这次服务器的响应里面不是 200 ok,而是304 Not Modified,这就是说它略过包体部分,让客户端直接去自己的缓存里拿数据。

我们修改cache2.txt文件

注意:以上红线划出来的地方,已经发生变化了

在处理上面那个cache2.txt 静态文件的例子时,客户端还可以使用 If-Modified-Since:Sun, 24 Sep 2017 05:27:44 GMT 来达到同样的效果(返回 304 响应)。这对于静态文件来说也很好用,因为响应头中的 Last-Modified 标识是根据服务器磁盘上的“更改时间戳”自动生成的。然而,“更改时间戳”对于动态文件通常没什么用,因为动态生成文件频繁更新,时间戳很难确定。我们都知道,你最想缓存起来的是内容,生成内容的代价是最大的,所以 ETag 头是更好的选择。

 Cache-Control头


 

Cache-Control 头相对来讲难一些。两个原因:

第一,Cache-Control 既可以用于请求头,也可以用于响应头。本文中着重讨论响应头,因为这是开发者所必须要掌握的。

第二,它控制着两个缓存:本地缓存(又称私有缓存)和共享缓存。

本地缓存,是指在客户端本地机器中的缓存。站在开发者的角度,它并不完全受你的控制,通常浏览器会自己决定是否把某些内容放到缓存中,这意味着:不要依赖于本地缓存。用户也可能在关闭浏览器的时候清理所有缓存,而你并不知道有这样的操作。除非你监测到了某个用户的流量不断上涨,导致缓存内容迅速失效,这时候你才会意识到。

共享缓存也就是本文所介绍的:处于客户端和服务器之间的缓存。即 CDN。你对共享缓存拥有绝对的控制,应该好好地利用它。

现在我们来用一些代码作为示例深入学习一下。

  1. Cache-Control: public max-age=3600
  2. Cache-Control: private immutable
  3. Cache-Control: no-cache
  4. Cache-Control: public max-age=3600 s-maxage=7200
  5. Cache-Control: public max-age=3600 proxy-revalidate

首先是缓冲能力,它关注的是缓存到什么地方,和是否应该被缓存。他的几个重要的属性是:

  • private表示它只应该存在本地缓存;
  • public表示它既可以存在共享缓存,也可以被存在本地缓存;
  • no-cache表示不论是本地缓存还是共享缓存,在使用它以前必须用缓存里的值来重新验证;
  • no-store表示不允许被缓存。

第二个是过期时间,很显然它关注的是内容可以被缓存多久。它的几个重要的属性是:

  • max-age=<seconds>:设置缓存时间,设置单位为秒。本地缓存和共享缓存都可以;
  • s-maxage=<seconds>:覆盖 max-age 属性。只在共享缓存中起作用。

最后一个是二次验证,表示精细控制。它的几个重要属性是:

  • immutable表示文档是不能更改的。
  • must-revalidate表示客户端(浏览器)必须检查代理服务器上是否存在,即使它已经本地缓存了也要检查。
  • proxy-revalidata表示共享缓存(CDN)必须要检查源是否存在,即使已经有缓存。

通过上面的具体解释,现在再来描述上面 Cache-Control 的那段代码所表达的意思就好理解多了:

  1. 本地缓存和 CDN 缓存均缓存 1 小时;
  2. 不能缓存在 CDN,只能缓存在本地。并且一旦被缓存了,则不能被更新;
  3. 不能缓存。如果一定要缓存的话,确保对其进行了二次验证;
  4. 本地缓存 1 小时,CDN 上缓存 2 小时;
  5. 本地和 CDN 均缓存 1 小时。但是如果 CDN 收到请求,则尽管已经缓存了 1 小时,还是要检查源中文档是否已经被改变。

 

 

 

 

 

 

 

 


 

目录
相关文章
|
1月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
2月前
|
缓存 JavaScript 前端开发
Vue 3 HTTP请求封装导致响应结果无法在浏览器中获取,尽管实际请求已成功。
通过逐项检查和调试,最终可以定位问题所在,修复后便能正常在浏览器中获取响应结果。
154 0
|
6月前
|
JSON API 网络架构
HTTP常见的请求方法、响应状态码、接口规范介绍
本文详细介绍了HTTP常见的请求方法、响应状态码和接口规范。通过理解和掌握这些内容,开发者可以更好地设计和实现W
977 83
|
4月前
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
367 20
|
11月前
|
缓存 移动开发 安全
Web安全-HTTP响应拆分(CRLF注入)漏洞
Web安全-HTTP响应拆分(CRLF注入)漏洞
670 1
HTTP状态码解析:在Haskell中判断响应成功与否
HTTP状态码解析:在Haskell中判断响应成功与否
|
7月前
|
API 数据安全/隐私保护
Haskell中的HTTP请求:代理与响应状态检查
Haskell中的HTTP请求:代理与响应状态检查
|
11月前
|
存储 JSON API
HTTP 请求与响应处理:C#中的实践
【10月更文挑战第4天】在现代Web开发中,HTTP协议至关重要,无论构建Web应用还是API开发,都需要熟练掌握HTTP请求与响应处理。本文从C#角度出发,介绍HTTP基础知识,包括请求与响应结构,并通过`HttpClient`库演示如何发送GET请求及处理响应,同时分析常见错误并提供解决方案,助你更高效地完成HTTP相关任务。
340 2
|
12月前
|
缓存 移动开发 安全
Web安全-HTTP响应拆分(CRLF注入)漏洞
Web安全-HTTP响应拆分(CRLF注入)漏洞
640 8
|
开发者
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
231 1

热门文章

最新文章