传输编码:gzip与内容编码:gzip

目前的情况是什么呢?

Transfer-Encoding: gzip 

或者一个

 Content-Encoding: gzip 

当我想让有限的带宽的客户 表示愿意接受压缩的响应时服务器最终决定是否压缩

后者是什么,如Apache的mod_deflate和IIS做的,如果你让它照顾压缩。 根据要压缩内容的大小,它将执行额外的Transfer-Encoding: chunked

它还将包括一个Vary: Accept-Encoding ,这已经暗示了这个问题。 Content-Encoding似乎是实体的一部分,所以改变Content-Encoding等于实体的变化,即不同的Accept-Encoding头意味着例如caching不能使用其它相同实体的caching版本。

有没有一个明确的答案,我已经错过了(这不是在一个apache新闻组的长线程中消息内)?

我目前的印象是:

  • 实际上,Transfer-Encoding是通过现有的服务器和客户端实现进行Content-Encoding的主要方式
  • 内容编码由于其语义含义而带有一些问题(当透明地压缩响应时,服务器应该如何处理ETag )?
  • 原因是chicken'n'egg:浏览器不支持它,因为服务器不是因为浏览器不支持

所以我假设正确的方式将是一个Transfer-Encoding: gzip (或者,如果我额外的块体,它将成为 Transfer-Encoding: gzip, chunked )。 在这种情况下没有任何理由碰VaryETag或任何其他头,因为它是一个运输级别的东西。

目前我并不太在意Transfer-Encoding的“逐跳”特性,这是别人似乎首先关心的,因为代理可能会解压缩并将未压缩的内容转发给客户端。 然而,如果原始请求具有正确的Accept-Encoding头,那么代理可能就像原来那样(压缩),在我知道的所有浏览器都是给定的情况下。

顺便说一句,这个问题至less有十年历史,请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=68517 。

任何澄清这一点将不胜感激。 无论是在什么被认为是符合标准的和什么被认为是实际的。 例如,仅支持透明“内容编码”的HTTP客户端库将成为违背实用性的论点。

引用RFC 2616的作者之一Roy T. Fielding

以不一致的方式改变内容编码(既不“永不”也不是永远)使得以后关于该内容(例如PUT或条件GET)的请求无法被正确处理,这当然是为什么执行即时的内容编码是一个愚蠢的想法,为什么我将转移编码添加到HTTP作为正确的方式来执行即时编码,而无需更改资源。

资料来源: https : //issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31

换句话说:不要进行即时的 Content-Encoding,而是使用Transfer-Encoding!

编辑:也就是说, 除非您想将gzip内容提供给仅了解Content-Encoding的客户端 。 不幸的是,这似乎是其中的大部分。 但是请注意,你离开了规范的领域,可能会遇到像Fielding和其他人所提到的问题,例如当涉及到caching代理时。

RFC 2616中定义的正确用法实际上是在野外实现的,用于客户端发送Accept-Encoding请求头(客户端可以指定多个编码)。 然后,服务器可以根据客户端支持的编码(如果文件数据尚未存储在该编码中)对响应进行编码,则在Content-Encoding响应头中指示正在使用哪种编码。 然后,客户端可以基于Transfer-Encoding (即, chunked )从套接字读取数据,然后基于Content-Encoding (即: gzip )对其进行解码。

所以,在你的情况下,客户端会发送一个Accept-Encoding: gzip请求头,然后服务器可以决定压缩(如果还没有的话)并发送Content-Encoding: gzip和可选的Transfer-Encoding: chunked响应头。

是的, Transfer-Encoding头可以在请求中使用,但只适用于HTTP 1.1,这要求客户端和服务器实现都在两个方向上支持chunked编码。

ETag唯一标识服务器上的资源数据,而不是实际传输的数据。 如果给定的URL资源更改其ETag值,则意味着该资源的服务器端数据已更改。

Interesting Posts