当涉及到是否进行时,当前情况如何
Transfer-Encoding: gzip
或
Content-Encoding: gzip
当我想允许带宽有限的客户端向发出他们愿意接受压缩响应的信号时,服务器对是否压缩拥有最终发言权。
后者就是Apache的mod_deflate和IIS所做的,如果你让它负责压缩的话。根据要压缩的内容的大小,它将执行额外的Transfer-Encoding: chunked
。
它还将包括一个Vary: Accept-Encoding
,它已经暗示了这个问题。Content-Encoding
似乎是实体的一部分,因此改变Content-Encoding
相当于实体的改变,即不同的Accept-Encoding
报头意味着例如高速缓存不能使用其在其他方面相同的实体的高速缓存版本。
关于这个问题,有没有一个我错过的确切答案(而且这个答案并没有隐藏在某个apache新闻组的长线程中的消息中)?
我目前的印象是:
- 传输编码实际上是实现现有服务器和客户端实现的内容编码的正确方法
- 由于内容编码的语义含义,它带来了几个问题(当
ETag
透明地压缩响应时,服务器应该对它做什么?) - 原因是胆小鬼:浏览器不支持它,因为服务器不支持,因为浏览器不支持
因此,我假设正确的方式是Transfer-Encoding: gzip
(或者,如果我另外对主体进行块化,它将变成Transfer-Encoding: gzip, chunked
)。在这种情况下,没有理由触摸Vary
或ETag
或任何其他标头,因为这是传输级别的东西。
目前,我不太关心Transfer-Encoding
的"逐跳"性,其他人似乎首先关心的是这一点,因为代理可能会解压缩并转发到客户端。然而,如果原始请求具有正确的Accept-Encoding
头,那么代理也可以原样转发(压缩)它,在我所知道的所有浏览器的情况下,这是一个给定的头。
顺便说一句,这个问题至少有十年的历史了,例如。https://bugzilla.mozilla.org/show_bug.cgi?id=68517。
如有任何澄清,我们将不胜感激。无论是从被认为符合标准的方面还是从被认为实用的方面。例如,只支持透明的"内容编码"的HTTP客户端库将是一个反对实用性的论点。
正确的用法,如RFC 2616中定义的,并在野外实际实现,是客户端发送Accept-Encoding
请求标头(客户端可以指定多个编码)。然后,服务器可以并且仅在那时,根据客户端支持的编码对响应进行编码(如果文件数据尚未以该编码存储),在Content-Encoding
响应报头中指示正在使用哪个编码。客户端然后可以基于Transfer-Encoding
(即chunked
)从套接字读取数据,然后基于Content-Encoding
(即:gzip
)对其进行解码。
因此,在您的情况下,客户端将发送Accept-Encoding: gzip
请求标头,然后服务器可能决定压缩(如果还没有)并发送Content-Encoding: gzip
和可选的Transfer-Encoding: chunked
响应标头。
是的,Transfer-Encoding
标头可以在请求中使用,但仅适用于HTTP1.1,它要求客户端和服务器实现都支持双向的chunked
编码。
ETag
唯一标识服务器上的资源数据,而不是实际传输的数据。如果给定的URL资源更改了其ETag
值,则表示该资源的服务器端数据已更改。
引用Roy T.Fielding,RFC 2616:的作者之一
以不一致的方式动态更改内容编码(既不是"从不"也不是"总是")使以后的请求无法进行关于要处理的内容(例如PUT或条件GET)正确地当然,这就是为什么要在飞行中表演内容编码是一个愚蠢的想法,以及为什么我添加了传输编码将HTTP作为在不更改的情况下进行动态编码的正确方式资源。
来源:https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31
换句话说:不要动态执行内容编码,而是使用传输编码!
编辑:也就是说,除非您想向只了解内容编码的客户端提供gzipped内容。不幸的是,这似乎是其中的大多数。但请注意,您离开了规范的领域,可能会遇到Fielding和其他人提到的问题,例如,当涉及缓存代理时。