If-Range 是什么
If-Range 是断点续传的安全阀。客户端把上次拿到的版本标识(强 ETag 或最后修改时间)连同 Range 请求一起发出,服务端只有在资源仍然与这个标识一致时,才返回 206 片段;一旦资源已经变化,就忽略范围请求、直接返回 200 完整内容。没有这个条件,下载中断后资源正好被替换,续传会拼出一个前后版本混杂的损坏文件。
基本信息
| 名称 | If-Range |
|---|---|
| 作用 | 保证分段下载基于同一版本资源 |
| 规范 | RFC 9110 §13.1.5 |
| 取值 | 强 ETag 或 HTTP 日期,只能一个值 |
| 禁止取值 | 以 W/ 开头的弱 ETag 不能用于此处 |
| 配套请求头 | Range,单独使用没有意义 |
断点续传请求
断点续传请求
curl -si -H 'Range: bytes=1048576-' -H 'If-Range: "v9-abc"' \
https://download.example.com/app.tar.gz | head -5
# 版本未变 → 206 Partial Content,媒体类型为片段
# 版本已变 → 200 OK,返回完整内容,需要重新开始下载
curl -sI https://download.example.com/app.tar.gz | grep -i etag # 先取 ETag四个条件头对照
| 请求头 | 判断依据 | 不满足时的结果 |
|---|---|---|
| If-Range | 强 ETag 或日期是否仍一致 | 忽略 Range,返回 200 完整内容 |
| If-Match | 资源 ETag 是否匹配 | 返回 412 Precondition Failed |
| If-Unmodified-Since | 资源是否在该时间后未被修改 | 返回 412 |
| If-None-Match | 资源 ETag 是否不同 | 返回 304,用于缓存校验 |
典型使用场景
- 大文件断点续传:下载器先取 ETag 再续传,避免跨版本拼接
- 分片下载工具:多个连接共享同一个版本标识,保证片段同源
- 客户端自动重试:网络中断后按偏移续传,同时校验资源未变
- 发布制品分发:上传新版本后旧客户端续传会被自动降级为全量下载
- 排障:解释为什么续传请求有时返回 200 而不是预期的 206
日期形式要求精确匹配,实际可靠性不如强 ETag;而带 W/ 前缀的弱 ETag 按规范不能用于 If-Range,遇到这种服务器配置时续传会一直退化成全量下载。排查时先确认响应里的 ETag 是强校验值还是弱校验值。若只能拿到日期,应确保它与资源的最后修改时间一致,而不是响应时间。