HTTP 条件请求(Conditional Requests)
字数 1272 2025-11-26 09:14:49
HTTP 条件请求(Conditional Requests)
-
基本概念
HTTP 条件请求是通过特定请求头来验证资源是否满足某些条件的机制。服务器仅在条件成立时执行操作(如返回资源或处理修改),否则返回状态码304 Not Modified(未修改时)或412 Precondition Failed(条件失败时)。核心价值在于减少冗余数据传输,提升缓存效率,并保证并发操作的安全性。 -
条件请求头分类
条件请求头分为两类:
- 验证器(Validators):描述资源状态,包括:
Last-Modified(响应头):资源最后修改时间。ETag(响应头):资源唯一标识符(如哈希值),分强校验(字节完全一致)与弱校验(内容语义一致)。
- 条件头(Conditional Headers):客户端携带的验证条件,包括:
If-Match:要求 ETag 与服务器当前资源匹配(常用于更新操作)。If-None-Match:要求 ETag 与服务器当前资源不匹配(常用于获取资源)。If-Modified-Since:要求资源在指定时间后被修改过(结合Last-Modified)。If-Unmodified-Since:要求资源在指定时间后未修改(结合Last-Modified)。
- 缓存更新流程
当客户端缓存了资源后,再次请求时通过条件头避免重复传输:
- 客户端发送请求并附加
If-None-Match: "abc123"(对应之前收到的ETag)。 - 服务器检查当前资源 ETag 是否为
"abc123":- 若匹配,返回
304 Not Modified(空响应体); - 若不匹配,返回
200 OK及最新资源。
此过程显著减少带宽消耗,尤其适用于大型静态资源(如图片、样式表)。
- 若匹配,返回
- 并发控制应用
在并发修改资源时(如协作编辑),条件请求防止数据覆盖:
- 客户端先获取资源,记录
ETag: "v1.0"。 - 修改后提交请求,附加
If-Match: "v1.0"。 - 服务器验证当前 ETag 是否仍为
"v1.0":- 若是,执行更新并生成新 ETag;
- 若否(资源已被他人修改),返回
412 Precondition Failed,提示客户端冲突。
- 高级场景与头组合
- 断点续传:下载大文件时,通过
If-Range头(配合ETag或Last-Modified)确保分段获取的资源未变更,否则需重新下载全文。 - 安全方法限制:对
POST或DELETE等非幂等操作使用If-Match,避免意外重复执行。 - 缓存与更新协同:浏览器自动对缓存资源添加
If-None-Match,而开发者可在 API 调用中显式使用If-Match实现乐观锁。
- 实际协议示例
以下为缓存验证的请求-响应交互:
// 首次请求
GET /data.json
响应: ETag: "xyz789", Last-Modified: Wed, 21 Oct 2020 07:28:00 GMT
// 条件请求
GET /data.json
If-None-Match: "xyz789"
If-Modified-Since: Wed, 21 Oct 2020 07:28:00 GMT
// 资源未变更时的响应
HTTP/1.1 304 Not Modified
通过条件请求,HTTP 协议实现了高效缓存、并发安全与网络优化,是 Web 性能与数据一致性的基石之一。