《图解HTTP》学习笔记
书籍信息 :《图解HTTP》作者:上野宣,译者:于均良
出版社:人民邮电出版社,2014年5月第1版
如果把 HTTP 通信比作寄快递,那报文就是那个快递盒子。盒子外面贴着标签(首部),里面装着东西(主体)。有时候东西太大,还得拆成几个小盒子分批寄(分块传输);有时候一个人寄好几种东西,就得用分隔板隔开(multipart)。今天我们就来拆快递盒子。
第3章 HTTP报文内的HTTP信息
📌 核心知识点
- HTTP报文结构:HTTP报文是用于HTTP协议交互的信息,由多行(CR+LF换行符)数据构成的字符串文本。分为报文首部和报文主体两部分,由空行(CR+LF)分隔。

- 请求报文结构:请求行(方法、URI、HTTP版本) + 报文首部(请求首部字段、通用首部字段、实体首部字段、其他) + 空行 + 报文主体。
- 响应报文结构:状态行(HTTP版本、状态码、原因短语) + 报文首部(响应首部字段、通用首部字段、实体首部字段、其他) + 空行 + 报文主体。

-
报文与实体的区别:
-
报文(message):HTTP通信的基本单位,由8位组字节流组成。
-
实体(entity):作为请求或响应的有效载荷数据被传输,由实体首部和实体主体组成。
-
通常报文主体等于实体主体,仅在传输中进行编码操作时才会产生差异。
-
内容编码(Content Coding):在传输时对实体内容进行压缩编码,提升传输速率。常用的内容编码:
-
gzip(GNU zip):最常用的压缩格式。
-
compress(UNIX系统标准压缩)。
-
deflate(zlib)。
-
identity(不进行编码)。

- 分块传输编码(Chunked Transfer Coding) :将实体主体分割成多块(chunk)发送,每块用十六进制标记大小,最后一块用
0(CR+LF)标记。使浏览器能逐步显示大容量数据页面。接收端负责解码恢复。

- 多部分对象集合(Multipart):在一份报文主体内含有多类型实体,常用于文件上传等场景。

使用boundary字符串划分各部分:
- multipart/form-data:Web表单文件上传时使用。

- multipart/byteranges:状态码206(Partial Content)响应包含多个范围内容时使用。

-
范围请求(Range Request) :指定资源的byte范围进行请求,用于断点续传等场景。使用
Range首部字段指定范围: -
Range: bytes=5001-10000(5001~10000字节) -
Range: bytes=5001-(从5001字节之后全部) -
Range: bytes=-3000, 5000-7000(多重范围) -
响应返回状态码206 Partial Content;若服务器不支持范围请求,返回200 OK和完整内容。

-
内容协商(Content Negotiation):客户端和服务器就响应资源内容进行交涉,提供最适合的资源。以语言、字符集、编码方式等为判断基准。
-
相关首部字段:
-
Accept
-
Accept-Charset
-
Accept-Encoding
-
Accept-Language
-
三种类型:
-
服务器驱动协商:服务器根据请求首部自动判断。
-
客户端驱动协商:用户从浏览器显示的选项中手动选择。
-
透明协商:服务器驱动和客户端驱动的结合体。

💻 实践用例
1. 查看完整的HTTP请求和响应报文
# 查看详细的请求和响应报文(包括首部和主体)
curl -v http://www.example.com/
# 查看响应头中的Content-Encoding(确认是否使用gzip压缩)
curl -v -H "Accept-Encoding: gzip" http://www.example.com/ 2>&1 | grep -i "content-encoding"
2. 使用范围请求实现断点续传
# 请求资源的第5001到10000字节
curl -H "Range: bytes=5001-10000" -v http://httpbin.org/robots.txt
# 请求从第100字节开始到末尾
curl -H "Range: bytes=100-" -v http://httpbin.org/robots.txt
# 多重范围请求
curl -H "Range: bytes=0-10, 20-30" -v http://httpbin.org/robots.txt
3. 模拟multipart/form-data表单上传
# 上传文件(multipart/form-data格式)
curl -X POST http://httpbin.org/post \
-F "field1=value1" \
-F "file=@/path/to/localfile.txt"
# 查看发送的multipart报文结构
curl -X POST http://httpbin.org/post \
-F "field1=value1" \
-F "file=@/path/to/localfile.txt" \
-v
4. 测试内容协商
# 请求中文版本的内容
curl -H "Accept-Language: zh-CN,zh;q=0.9" http://www.example.com/
# 请求JSON格式
curl -H "Accept: application/json" http://httpbin.org/get
# 请求gzip压缩的内容
curl -H "Accept-Encoding: gzip, deflate" --compressed http://www.example.com/
5. 使用Python发送范围请求
import requests
# 断点续传示例:从第1000字节开始下载
headers = {'Range': 'bytes=1000-'}
response = requests.get('http://example.com/largefile.zip', headers=headers)
print(f"状态码: {response.status_code}") # 206 Partial Content
print(f"Content-Range: {response.headers.get('Content-Range')}")
print(f"下载字节数: {len(response.content)}")
📝 学习笔记
- 报文首部是HTTP通信的"元数据" :首部字段承载了内容类型、编码方式、缓存策略、认证信息等关键信息。理解首部字段是调试HTTP问题的关键能力。使用
curl -v是查看首部字段最快捷的方式。 - 内容编码与传输编码是两个不同概念:内容编码(Content-Encoding)是对实体主体进行压缩,目的是减小传输体积;传输编码(Transfer-Encoding)是改变数据传输方式,如分块传输编码。不要混淆两者。
- 分块传输编码的实用价值:当服务器不知道响应体的总大小时(如动态生成的内容),可以使用分块传输编码。这在流式传输(视频直播、Server-Sent Events)场景中非常重要。
- 范围请求是断点续传的技术基础:下载工具(如wget、迅雷)的断点续传功能就是基于范围请求实现的。在开发文件下载API时,支持Range首部能显著提升用户体验。
- 内容协商在现代Web开发中无处不在:RESTful API通过Accept首部返回JSON或XML,浏览器通过Accept-Language显示对应语言版本,通过Accept-Encoding返回压缩内容。理解内容协商有助于设计更灵活的API。
- multipart/form-data是文件上传的标准格式 :在HTML表单中设置
enctype="multipart/form-data"即使用此格式。boundary字符串用于分隔各部分,每个部分可以有自己的Content-Type和Content-Disposition。
报文结构、内容编码、分块传输、范围请求、内容协商......这章干货密度很高,建议收藏备用。特别是范围请求------下次下载到一半断网的时候,你可以骄傲地说:我知道这是怎么实现的!下一章聊聊快递到达后,盒子上贴的那个三位数字"签收状态"是什么意思。