分块编码和内容长度标头

Posted

技术标签:

【中文标题】分块编码和内容长度标头【英文标题】:Chunked encoding and content-length header 【发布时间】:2011-03-19 06:17:30 【问题描述】:

是否可以设置内容长度标头并使用分块传输编码?这样做是否解决了使用chunked时客户端不知道响应长度的问题?

我正在考虑的场景是当您有一个大文件要传输并且确定其大小没有问题,但它太大而无法完全缓冲。 (如果你不使用分块,那么整个响应必须先缓冲?对吗??)

谢谢。

【问题讨论】:

【参考方案1】:

您必须使用 Content-Length 或分块,但不能同时使用。

如果您事先知道长度,您可以使用 Content-Length 而不是分块,即使您动态生成内容并且永远不会一次将所有内容都放在缓冲区中。

但是,如果数据非常大,则不应这样做,因为代理可能无法处理它。对于大数据,分块更安全。

【讨论】:

很遗憾,如果您需要下载带有进度信息的大文件,这对您没有帮助。 规范只说如果存在 Transfer-Encoding 则忽略 Content-Length,并没有说你不能发送它,基于对 chrome 的试验,chrome 会处理 Content-Length作为提示(如果存在),并显示文件下载的进度条。如果我发送的内容长度太短,它会显示进度条,直到下载超过指示的长度,然后切换到流式传输进度条,仍然可以正确完成下载。 当我将 Content-Length 设置得太大时,这也有效,下载按照分块规则停止。基于此,我将对大文件使用分块并设置 Content-Length ,唯一可能存在问题的情况是客户端不符合标准并且 Content-Length 优先于 Transfer-Encoding,因此我认为它应该' 不是任何主要网络浏览器的问题(基于使用统计) IE 可能是一个问题,但从内存来看,这些天它只有大约 2% 的网络用户,所以我不在乎。【参考方案2】:

好吧,您总是可以发送一个标明文件大小的标头。 类似response.addHeader("File-Size","size of the file"); 并忽略 Content-Length 标头。 必须调整客户端实现以读取此值,但是您可以同时实现您想要的东西:)

【讨论】:

简单的解决方案是最好的:-) 约定是在任何非标准标头上使用X- 前缀。 HTTP 代理很可能会决定丢弃您的非标准非 X 标头。 感谢 MSalters,刚刚在其他地方引用了类似的指南,不胜感激。 截至 5 年前,非标准标头上的 X- 前缀不受欢迎、已弃用且不被视为最佳做法。只要继续使用file-size 作为标题名称,就可以了。 tools.ietf.org/html/rfc6648【参考方案3】:

1) 否:“消息不得同时包含 Content-Length 标头字段和非身份传输编码。如果消息确实包含非身份传输编码,则必须忽略 Content-Length。” (RFC 2616, Section 4.4)

2) 不,您可以使用 Content-Length 和流;该协议不会限制您的实现方式。

【讨论】:

我希望分块传输编码是流的一个例子;你在这里提到过不是吗?它还可能包括范围请求。我说的对吗?

以上是关于分块编码和内容长度标头的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用传输编码:chunked websphere

如何使用带有“传输编码:分块”的 winhttp api

Content-Length 标头与分块编码

用于分块编码 POST 的 HTTP 标头 - 错误 411

转基于内容可变长度分块(CDC)

防止 Apache 对 gzip 内容进行分块