传输编码: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
)。 在这种情况下没有任何理由碰Vary
或ETag
或任何其他头,因为它是一个运输级别的东西。
目前我并不太在意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
值,则意味着该资源的服务器端数据已更改。