Content-Length标头与分块编码

Gan*_*alf 34 performance http chunked-encoding content-length

我试图权衡设置Content-LengthHTTP标头与使用分块编码从我的服务器返回[可能]大文件的优缺点.需要使用持久连接来满足HTTP 1.1规范中的一个或另一个.我看到Content-Length标题的优点是:

  • 下载对话框可以显示准确的进度条
  • 如果文件可能/可能不太大而无法摄取,则客户端会提前知道

缺点是必须在返回对象之前计算大小,这并不总是实用并且可能会增加服务器/数据库利用率.分块编码的缺点是在每个块和下载进度条之前添加块大小的开销很小.有什么想法吗?我可能没有想到的两种方法的任何其他HTTP注意事项?

Pis*_*3.0 32

绝对使用Content-Length.此服务器的利用率几乎不存在,对用户的好处将很大.

对于动态内容,添加压缩响应支持(gzip)也非常简单.这需要输出缓冲,这反过来为您提供内容长度.(对于文件下载或已经压缩的内容(声音,图像)不实用).

还要考虑添加对部分内容 /字节范围服务的支持 - 即重启下载的功能.请参阅此处获取字节范围示例(该示例在PHP中,但适用于任何语言).在提供部分内容时,您需要Content-Length.

当然,那些不是银子弹:对于流媒体,使用输出缓冲或响应大小是没有意义的; 对于大文件,输出缓冲没有意义,但内容长度和字节服务很有意义(重启失败的下载是可能的).

就我个人而言,每当我知道它时,我都会提供Content-Length; 对于文件下载,检查文件大小在资源方面是微不足道的.结果:用户有一个确定的进度条(由于gzip,动态页面下载速度更快).

  • 是的,这是真的.BTW:GZIP不需要输出缓冲.它默认以分块编码发送.至少,在Java servletcontainers中. (4认同)

Bal*_*usC 12

如果事先已知内容长度,那么我肯定更愿意在上面发送内容.如果本地磁盘文件系统或数据库中存在静态文件,那么任何自尊的编程语言和RDBMS都会提供预先获取内容长度的方法.你应该利用它.

另一方面,如果内容长度事先确实不可预测(例如,当您的意图是将多个文件压缩在一起并将其作为一个文件一起发送时),那么以块的形式发送它可能比在服务器的内存中缓冲它或写入本地磁盘更快文件系统首先.但这确实会对用户体验产生负面影响,因为下载进度未知.然后,不耐烦的人可以中止下载并继续前进.

预先知道内容长度的另一个好处是能够恢复下载.我在你的帖子历史中看到你的主要编程语言是Java; 你可以在这里找到一篇包含更多技术背景信息的文章和一个Java Servlet示例.


Dha*_*era 5

内容长度

所述Content-Length报头确定所述请求/响应身体的字节长度。如果您忽略指定Content-Length标头,则HTTP服务器将隐式添加Transfer-Encoding: chunked标头。的Content-LengthTransfer-Encoding标头不应该被一起使用。接收者将不知道主体的长度,并且无法估计下载完成时间。如果添加Content-Length标头,请确保它与整个字节匹配,如果不正确,则接收器的行为不确定。

Content-Length头将不允许流,但它是大的二进制文件,要支持部分的内容服务是有用的。这基本上意味着可恢复的下载,暂停的下载,部分下载和多宿主下载。这需要使用称为的附加标头Range。这种技术称为字节服务

传输编码

使用Transfer-Encoding: chunked允许在单个请求或响应中进行流式传输。这意味着数据以分块方式传输,并且不影响内容的表示。

正式而言,HTTP客户端旨在发​​送带有TE标头字段的请求,该标头字段指定客户端愿意接受的传输编码类型。这并不总是发送,但是大多数服务器都假定客户端可以处理chunked编码。

chunked传输编码使得更好地利用持续TCP连接,这HTTP 1.1已经被认为是默认为true的。

内容编码

也可以压缩分块或非分块数据。实际上,这是通过Content-Encoding标题完成的。

请注意,Content-Length等于后的主体长度Content-Encoding。这意味着如果压缩了响应,则长度计算将在压缩后进行。如果要计算长度,您将需要能够将整个主体加载到内存中(除非您在其他地方有该信息)。

使用分块编码进行流传输时,压缩算法还必须支持在线处理。幸运的是,gzip支持流压缩。我相信内容会先被压缩,然后再切成块。这样,接收块,然后解压缩以获取真实内容。如果不是这样,您将获得压缩流,然后解压缩将获得大量数据。这没有意义。

典型的压缩流响应可能具有以下标头:

Content-Type: text/html
Content-Encoding: gzip
Transfer-Encoding: chunked
Run Code Online (Sandbox Code Playgroud)

语义上的用法Content-Encoding表示“端到端”编码方案,这意味着仅最终客户端或最终服务器才应解码内容。中间的代理不应该解码内容。

如果要允许中间的代理解码内容,则实际上要使用的正确标头是Transfer-Encoding标头。如果HTTP请求拥有TE: gzip chunked标头,则使用响应是合法的Transfer-Encoding: gzip chunked

但是,很少有人支持。因此,您现在应该只Content-Encoding用于压缩。

分块与存储和转发