飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • HTTP 基础

    • 认识HTTP协议与应用层定位
    • HTTP消息格式与报文结构
    • HTTP请求方法与幂等性
    • HTTP状态码详解
  • 连接与缓存

    • HTTP持久连接与版本演进
    • HTTP缓存机制
  • 状态与协商

    • Cookie与Session状态管理
    • HTTP重定向与内容协商
    • HTTP条件请求与范围请求
  • 安全与加密

    • HTTP认证机制
    • HTTPS与TLS握手
  • 协议演进

    • HTTP2核心特性
    • HTTP3与QUIC
  • 架构与实战

    • HTTP代理服务器与Web缓存
    • HTTP常见攻击与防御
    • HTTP实践工具与抓包分析

HTTP条件请求与范围请求

概念引入

想象你去图书馆借书,管理员不会每次都把书从书架上取下来重新检查——她会先看登记卡:"这本书上次借出后有没有更新版本?"如果没有,直接告诉你"还是老样子,不用看了"。

条件请求(Conditional Request)就是这个思路:客户端在请求时带上"验证器",服务器比较后决定是否执行操作。如果资源没变化,直接返回 304 Not Modified,省去重复传输。

而范围请求(Range Request)则像你去蛋糕店说:"我只要中间那块草莓的,不要整个蛋糕"。客户端只请求资源的一部分,服务器返回 206 Partial Content。

在飞翔科技,凌叔(运维)经常需要更新服务器上的部署包,空少(前端)则负责官网视频播放。条件请求和范围请求正是他们日常工作的技术基石。


核心内容

验证器:资源的"身份证"

服务器给每个资源配两张"身份证":

验证器比喻特点
Last-Modified书的"最后修订日期"时间戳,精度到秒,可能不够精准
ETag书的"指纹/哈希值"内容稍有变化就完全不同,更可靠

ETag(Entity Tag)是服务器为资源生成的唯一标识符,通常基于文件内容的哈希计算。就像给文件按了个"指纹"——内容变一比特,指纹全变。

HTTP/1.1 200 OK
Last-Modified: Wed, 21 Oct 2026 07:28:00 GMT
ETag: "33a64df5-0012b"
Content-Type: application/octet-stream

条件请求头:五员大将

客户端携带验证器,通过以下请求头发起条件请求:

If-Modified-Since / If-Unmodified-Since

用 Last-Modified 做比较:

GET /deploy/package.zip HTTP/1.1
Host: www.feixiang.net
If-Modified-Since: Wed, 21 Oct 2026 07:28:00 GMT
  • 资源在此时间后修改过 → 返回 200 OK + 新内容
  • 资源未修改 → 返回 304 Not Modified

If-Unmodified-Since 则相反:如果资源已被修改,返回 412 Precondition Failed(前置条件失败)。

场景:航仔(后端)上传新代码前,先检查"如果部署包没被人动过,我才覆盖"。

If-None-Match / If-Match

用 ETag 做比较,更精准:

GET /api/v2/config.json HTTP/1.1
Host: www.feixiang.net
If-None-Match: "33a64df5-0012b"
  • ETag 不匹配 → 返回 200 OK + 新内容
  • ETag 匹配 → 返回 304 Not Modified

If-Match 常用于 PUT/DELETE:"只有资源还是这个版本,我才修改/删除"。

场景:图妹(产品经理)和星宇(产品助理)同时编辑需求文档。图妹先保存,ETag 变为 "v2"。星宇保存时带的还是 "v1",服务器返回 412 Precondition Failed,防止覆盖。

If-Range

If-Range 是范围请求的"保险栓":先检查资源是否变化,没变才发范围内容,否则发完整内容。

GET /video/intro.mp4 HTTP/1.1
Host: www.feixiang.net
Range: bytes=1024000-2047999
If-Range: "abc123"
  • ETag 匹配 → 返回 206 Partial Content
  • ETag 不匹配 → 返回 200 OK(完整内容,避免客户端拿到过时的片段)

范围请求:只取所需

Range 头的格式

Range: bytes=0-1023          # 第0到1023字节(共1024字节)
Range: bytes=1024-2047       # 第1024到2047字节
Range: bytes=-500            # 最后500字节
Range: bytes=500-            # 从第500字节到末尾
Range: bytes=0-1023,2048-3071 # 多段范围(多段响应用 multipart/byteranges)

服务器响应

HTTP/1.1 206 Partial Content
Content-Range: bytes 1024000-2047999/5242880
Content-Length: 1024000

[二进制数据...]

Content-Range 响应头格式:bytes 起始-结束/总大小

应用场景

飞翔公司场景:

  1. 断点续传:凌叔下载 5GB 的日志备份,下到 2GB 时断网。重连后发送 Range: bytes=2147483648-,从断点继续,不用从头再来。

  2. 视频拖拽:空少做的官网宣传视频,用户直接拖到第 5 分钟。播放器发送 Range: bytes=5242880-,秒开播放。

  3. 大文件分段下载:风速(算法)训练用的数据集 10GB,下载工具开 8 个线程,每个线程请求不同 Range,并行下载后合并。


本篇小结

  • 条件请求通过验证器(Last-Modified/ETag)避免重复传输未变更的资源,节省带宽
  • If-Modified-Since / If-None-Match 用于缓存刷新,匹配则返回 304 Not Modified
  • If-Match / If-Unmodified-Since 用于并发控制,不匹配则返回 412 Precondition Failed
  • If-Range 是范围请求的"保险栓",确保片段与整体版本一致
  • 范围请求通过 Range: bytes=起始-结束 只获取资源片段,服务器返回 206 Partial Content
  • Content-Range 头告知客户端返回的是哪一段、总长度多少
  • 典型应用:断点续传、视频拖拽、大文件多线程下载、缓存优化

动手实践

温馨提示: 以下实践示例中涉及的域名(如 www.feixiang.net)、公司场景和接口均为虚构数据,仅用于演示协议原理,实际执行时可能不会产生文档中描述的效果。建议将命令中的域名替换为你自己可访问的真实地址进行练习。

实践:用 curl 测试条件请求

# 先获取资源的 ETag
curl -I http://www.feixiang.net/static/logo.png

# 带上 If-None-Match 再次请求(如果未修改,返回 304)
curl -I -H 'If-None-Match: "abc123"' http://www.feixiang.net/static/logo.png

实践:用 curl 测试范围请求

# 只下载前 1024 字节
curl -r 0-1023 http://www.feixiang.net/download/setup.exe -o setup_head.exe

# 下载第 1024 到 2047 字节
curl -r 1024-2047 http://www.feixiang.net/download/setup.exe -o setup_part2.exe

实践:思考题

  1. 为什么 ETag 比 Last-Modified 更可靠?如果服务器在 1 秒内多次修改文件,Last-Modified 会出什么问题?
  2. 假设图妹和星宇同时编辑同一个文档,如何用 If-Match 实现"乐观锁"防止覆盖?画出请求时序图。
  3. 断点续传时,如果服务器不支持 Range 请求,会返回什么状态码?客户端应该如何降级处理?

查看思考题答案

上一页
HTTP重定向与内容协商