什么是分块传输编码?
无抓取通用抓取 API 通过一个管理的请求表面检索公共 web 内容,该表面可以返回响应体,而不要求客户端控制源服务器的消息成帧。
简单来说
- 分块传输编码是一种 HTTP/1.1 消息成帧方法,该方法在发送方未提供完整正文长度的情况下,将正文作为一系列独立大小的块发送。 分块的实际原因在于定时。
- 读取传输编码。 接收者检查 Transfer-Encoding,并将最终编码视为成帧规则。当存在分块时,Content-Length 不能定义相同的消息体。冲突的成帧元数据是危险的,因为不同的中介可能对请求或响应的结束位置有不同的看法。
- 准确消费数据和分隔符。 在大小行之后,解析器消费声明的字节数,然后是所需的行结束。大小不匹配、缺少分隔符或在零块之前连接关闭会使消息不完整。经过充分测试的 HTTP 库在暴露正文给应用代码之前处理这些边界逻辑。
- 在每个相关的跳点确认协商的 HTTP 版本,而不是从浏览器 URL 推断。 当分块响应看起来被截断时,首先识别哪个跳点导致了故障。
- 分块传输编码解决了一个具体的 HTTP/1.1 问题:如何划定一个在发送开始之前未知最终字节长度的正文。
定义和简短回答
分块传输编码是一种 HTTP/1.1 消息成帧方法,该方法在发送方未提供完整正文长度的情况下,将正文作为一系列独立大小的块发送。每个块以其十六进制大小开始,随后是相应数量的字节数据,最后以回车符和换行符对结束。零大小的块标志着正文的结束。该机制在一个网络跳点上成帧消息;它不定义媒体类型,不自行压缩表示,也不将资源分割为独立的可寻址文件。
分块的实际原因在于定时。一个应用程序可能逐行生成报告、从另一个服务流式输出,或者在每个字节都已知之前开始发送动态渲染的响应。HTTP/1.1 否则需要一个可靠的边界,通常是 Content-Length 字段或连接关闭。分块成帧提供了这个边界,同时允许连接保持持续。接收方可以解析每个大小行,准确消费声明的字节数,并在不等待服务器关闭套接字的情况下识别完成。
分块传输编码是逐跳的。反向代理可以接收分块响应,解码它,缓冲或转换内容,并以 Content-Length 或不同的块布局转发它。因此,应用代码应该关心解码后的正文和响应完整性,而不是假设在某个时刻观察到的块能够在端到端存活。Content-Encoding 是不同的:gzip 或其他内容编码描述了请求路径中表示的编码方式,而 Transfer-Encoding 描述了相邻 HTTP 参与者之间的成帧。
HTTP/2 和 HTTP/3 不使用 HTTP/1.1 Transfer-Encoding 头进行正文成帧。这些协议在其自己的二进制帧层中承载数据。开发者仍然可能看到流式数据,但传输表示不是 HTTP/1.1 的分块编码。这个区别在日志和调试工具中很重要,因为网关可以接受浏览器的 HTTP/2 并与源进行 HTTP/1.1 通信,在路由的一个环节上创建分块流量。
HTTP/1.1 分块正文是如何成帧的
- 读取传输编码。 接收者检查 Transfer-Encoding,并将最终编码视为成帧规则。当存在分块时,Content-Length 不能定义相同的消息体。冲突的成帧元数据是危险的,因为不同的中介可能对请求或响应的结束位置有不同的看法。
- 解析十六进制大小。 每个块以一个或多个十六进制数字开始。该值计数数据字节,而不是可见字符。因此,多字节文本不能通过 JavaScript 字符串长度或字符计数来衡量;成帧在转换时按字节操作。
- 准确消费数据和分隔符。 在大小行之后,解析器消费声明的字节数,然后是所需的行结束。大小不匹配、缺少分隔符或在零块之前连接关闭会使消息不完整。经过充分测试的 HTTP 库在暴露正文给应用代码之前处理这些边界逻辑。
- 以最后一个块结束。 零大小的块结束了块序列。可选的尾部部分可以在最后的空行之前跟随,但只有在流媒体后可以计算的字段才能适用尾部。它们不能修复接收者在阅读正文之前所需的缺失头部。
现实系统中的分块传输编码
生成的响应
服务器可以在数据库查询仍在生成行时开始发送大量导出,从而减少客户端接收有用字节之前的时间。
反向代理管道
网关可以将上游数据流式传输到客户端,而不缓冲完整表示,受其自身转换和缓冲设置的约束。
服务器发送的输出
渐进的文本或事件式输出可以通过HTTP/1.1连接分块到达,即使应用程序只消耗一个逻辑响应体。
未知的最终大小
模板、压缩流和聚合服务可能不知道编码的字节数,直到生成结束,使得预先计算的Content-Length不实用。
与附近概念比较的分块编码
并排视图防止附近概念被视为可互换。使用比较来识别哪个合同在活动之前更改客户端或服务器行为。
| 概念或信号 | 含义 | 操作说明 |
|---|---|---|
| Content-Length | 在传输之前声明完整的主体大小 | 在已知且稳定的编码长度时使用 |
| 分块传输编码 | 将HTTP/1.1主体框架划分为大小块 | 在发送之前不知道最终大小时使用 |
| 连接关闭 | 使用套接字关闭作为主体边界 | 防止连接重用的遗留后备方案 |
| 内容编码 | 转换表示字节,如压缩 | 与消息框架无关 |
| HTTP/2数据帧 | 在协议帧中承载主体字节 | 在HTTP/2链接上替换HTTP/1.1分块框架 |
分块传输编码诊断和操作设计
当分块响应显示被截断时,首先要确定哪个跳跃产生了故障。浏览器开发者工具通常显示解码后的主体,而数据包捕获或详细的命令行客户端可以揭示线缆级大小信息。通过请求标识符比较源、网关、内容交付网络和客户端日志。完整的应用负载仍然可能由于代理超时而被截断,而且正确的零块仍然可以包含逻辑上不完整的应用文档。
不要手动解块正常HTTP客户端返回的响应。成熟的客户端会去除传输框架,并公开字节流或解码主体。再次解析块标记可能会破坏合法内容,恰好包含十六进制行。手动解析应属于协议测试、网络诊断、服务器、代理和专用客户端,在这些地方原始字节是故意可用的。
安全审查应将模糊框架视为协议问题,而不是外观头部问题。携带冲突长度信号的消息可以被相邻系统以不同方式解释。在受信任的边界标准化传入请求,拒绝格式错误的框架,保持代理和源行为一致,避免将模糊消息传递到应用程序栈的更深层次。
分块传输编码实施检查清单
下面的检查清单将概念转化为可验证的工程工作。仅应用与活动协议和产品合同匹配的项目,但将证据保持在一起,以便其他工程师可以重建决策。
- 在每个相关跳跃上确认协商的HTTP版本,而不是从浏览器URL推测。
- 同时检查Transfer-Encoding和Content-Length;有效框架不得要求接收者在冲突边界之间进行选择。
- 以八位字节测量块大小,并在原始解析是测试系统的一部分时验证所需的行结束。
- 记录网关是否缓存、解压缩或重构主体,因为这些步骤会改变下游工具观察到的内容。
- 使用请求标识符将客户端、代理和源证据连接起来,以处理不完整消息。
- 在受控环境中测试早期连接关闭和格式错误的最终块,以便故障显式。
- 让标准HTTP库向应用程序代码公开解码的主体,除非协议实现是实际任务。
实施后,在受控环境中测试正常行为、边界、格式错误输入、缺失状态、并发活动和故意拒绝访问。记录每种情况的预期状态、主体形状、结束条件和状态转换。生产监控应报告在测试中使用的相同维度,以便可以将事件与已知的基线进行比较。
文档应在接口的每一侧命名责任。客户端需要必需字段、稳定标识符、排序规则、限制、终端信号和错误含义。操作人员需要内部政策、存储或路由决策、可观察字段和安全的公共响应。模糊合同导致团队在错误的层次上修复可见症状。
与分块传输编码的常见错误
不要仅从一个字段推测成功、缺失、权限、排序或完成,而是要考虑周围的合同。状态码、令牌、页面大小和传输头分别回答狭窄的问题。响应体、方法、身份、过滤器、协议版本和服务器文档提供其余含义。
不要以简化的名义去除诊断上下文。省略请求标识符、目标、版本、范围或边界的短日志行可以将小缺陷变成几小时的猜测。同时,可观察性必须删除凭据、会话密钥、签名URL和敏感有效负载字段。
不要将临时操作解决方法变成永久合同。修复根本的排序、权限、路由、节奏、框架或错误映射问题,并添加回归检查。一个系统会变得可靠,当故障明确且有限,而不是发生一次手动运行恰好完成。
结论
分块传输编码解决了一个明确的HTTP/1.1问题:如何限定一个在发送开始之前不知道的最终字节长度的主体。它的十六进制大小、数据段、零块和可选的尾部属于单跳的传输框架。应用程序通常会消费解码的主体,而操作员仅在追踪不完整响应、代理变换或框架冲突时检查原始块。
准备构建一个更可靠的数据工作流程吗?
将本指南中的协议概念与记录在案的Scrapeless产品表面相联系,并保持每个请求从提交到结果都是可衡量的。
今天注册并获取 $5的免费信用 — 无需信用卡.
领取您的$5信用→常见问题解答
分块传输编码与流式传输一样吗?
不一样。分块传输编码是一种支持渐进交付的HTTP/1.1帧机制,但流式传输是一种更广泛的应用行为。HTTP/2和HTTP/3可以通过自己的帧系统流式传输响应数据,而无需Transfer-Encoding: chunked头。
分块响应也可以包含Content-Length吗?
有效的HTTP/1.1消息在Transfer-Encoding定义帧的情况下,不应使用Content-Length来框定主体。冲突信号会产生歧义,应在受信边界被拒绝或规范化。
每个块对JavaScript可见吗?
通常不可见。浏览器和HTTP客户端库在暴露响应数据之前会解码块帧。应用代码可能接收流段,但这些段不必与发送者或中介选择的线路块相匹配。
零大小块是什么意思?
零大小块标志着块序列的结束。可选的后续字段可以跟随它,最后一个空行完成消息。如果连接提前结束,接收方应将主体视为不完整。
为什么块边界通过代理会变化?
传输编码是逐跳进行的,因此代理可以解码、缓冲、转换和重新框定主体。即使交付给应用程序的表示是相同的,下游块大小可能与上游大小不同。