一文带你了解 HTTP 黑科技(11)


  • 对于 安全 的方法 , 像是 GET、用于请求文档的资源 , 仅当条件请求的条件满足时发回文档资源 , 所以 , 这种方式可以节约带宽 。
什么是安全的方法 , 对于 HTTP 来说 , 安全的方法是不会改变服务器状态的方法 , 换句话说 , 如果方法只是只读操作 , 那么它肯定是安全的方法 , 比如说 GET 请求 , 它肯定是安全的方法 , 因为它只是请求资源 。几种常见的方法肯定是安全的 , 它们是 GET、HEAD和 OPTIONS 。所有安全的方法都是幂等的(这他妈幂等又是啥意思?)但不是所有幂等的方法都是安全的 , 例如 PUT 和 DELETE 都是幂等的 , 但不安全 。
幂等性:如果相同的客户端发起一次或者多次 HTTP 请求会得到相同的结果 , 则说明 HTTP 是幂等的 。(我们这次不深究幂等性)
  • 对于 非安全 的方法 , 像是 PUT , 只有原始文档与服务器上存储的资源相同时 , 才可以使用条件请求来传输文档 。(PUT 方法通常用来传输文件 , 就像 FTP 协议的文件上传一样)
验证所有的条件请求都会尝试检查服务器上存储的资源是否与某个特定版本的资源相匹配 。为了满足这种情况 , 条件请求需要指示资源的版本 。由于无法和整个文件逐个字符进行比较 , 因此需要把整个文件描绘成一个值 , 然后把此值和服务器上的资源进行比较 , 这种方式称为比较器 , 比较器有两个条件
  • 文档的最后修改日期
  • 一个不透明的字符串 , 用于唯一标识每个版本 , 称为实体标签或 Etag 。
比较两个资源是否时相同的版本有些复杂 , 根据上下文 , 有两种相等性检查
  • 当期望的是字节对字节进行比较时 , 例如在恢复下载时 , 使用强 Etag进行验证
  • 当用户代理需要比较两个资源是否具有相同的内容时 , 使用若 Etag 进行验证
HTTP 协议默认使用 强验证 , 它指定何时进行弱验证
强验证强验证保证的是字节 级别的验证 , 严格的验证非常严格 , 可能在服务器级别难以保证 , 但是它能够保证任何时候都不会丢失数据 , 但这种验证丢失性能 。
要使用 Last-Modified 很难实现强验证 , 通常 , 这是通过使用带有资源的 MD5 哈希值的 Etag 来完成的 。
弱验证弱验证不同于强验证 , 因为如果内容相等 , 它将认为文档的两个版本相同 , 例如 , 一个页面与另一个页面的不同之处仅在于页脚的日期不同 , 因此该页面被认为与其他页面相同 。而使用强验证时则被认为这两个版本是不同的 。构建一个若验证的 Etag 系统可能会非常复杂 , 因为这需要了解每个页面元素的重要性 , 但是对于优化缓存性能非常有用 。
下面介绍一下 Etag 如何实现强弱验证 。
Etag 响应头是特定版本的标识 , 它能够使缓存变得更高效并能够节省带宽 , 因为如果缓存内容未发生变更 , Web 服务器则不需要重新发送完整的响应 。除此之外 , Etag 能够防止资源同时更新互相覆盖 。
一文带你了解 HTTP 黑科技

文章插图
 
如果给定 URL 上的资源发生变更 , 必须生成一个新的 Etag 值 , 通过比较它们可以确定资源的两个表示形式是否相同 。
Etag 值有两种 , 一种是强 Etag , 一种是弱 Etag;
  • 强 Etag 值 , 无论实体发生多么细微的变化都会改变其值 , 一般的表示如下
Etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 弱 Etag 值 , 弱 Etag 值只用于提示资源是否相同 。只有资源发生了根本改变 , 产生差异时才会改变 Etag 值 。这时 , 会在字段值最开始处附加 W/ 。
Etag: W/"0815"下面就来具体探讨一下条件请求的标头和 Etag 的关系
条件请求条件请求主要包含的标头如下
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-Since
  • If-Range
If-Match对于 GET 和 POST 方法 , 服务器仅在与列出的 Etag(响应标头) 之一匹配时才返回请求的资源 。这里又多了一个新词 Etag , 我们稍后再说 Etag 的用法 。对于像是 PUT 和其他非安全的方法 , 在这种情况下 , 它仅仅将上传资源 。


推荐阅读