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

当谈到是否这样做时,目前的情况是什么

Transfer-Encoding: gzip

或者

Content-Encoding: gzip

当我想允许 客户与例如有限的带宽到 表明他们愿意接受压缩回应服务器对是否压缩有最终决定权

后者就是 Apache 的 mod _ flate 和 IIS 所做的,如果你让它负责压缩的话。根据要压缩的内容的大小,它将执行额外的 Transfer-Encoding: chunked

它还将包括一个 Vary: Accept-Encoding,这已经暗示了问题。Content-Encoding似乎是实体的一部分,因此更改 Content-Encoding等于更改实体,即不同的 Accept-Encoding头意味着缓存不能使用其缓存版本的其他相同的实体。

对于这个问题,我是否遗漏了一个明确的答案(而且这个答案没有隐藏在某个 apache 新闻组的长线程中的消息中) ?

我现在的印象是:

  • 传输-编码实际上是正确的方法,通过现有的服务器和客户端实现对 Content-Encoding 进行处理
  • 内容编码,由于它的语义含义,带来了一些问题(当服务器透明地压缩响应时,它应该对 ETag做什么?)
  • 原因是先有鸡还是先有蛋: 浏览器不支持它,因为服务器不支持,因为浏览器不支持

因此,我假设正确的方式是 Transfer-Encoding: gzip(或者,如果我额外组块的身体,它 会变成 Transfer-Encoding: gzip, chunked)。在这种情况下,没有理由触摸 VaryETag或任何其他头部,因为它是一个传输级别的东西。

目前,我不太关心 Transfer-Encoding的“一跳一跳”,其他人似乎首先关心的是这个问题,因为代理可能会解压缩并向客户端转发。但是,如果原始请求具有适当的 Accept-Encoding头文件,那么代理也可以将其转发为-is (压缩) ,在我所知道的所有浏览器中,Accept-Encoding头文件都是给定的。

顺便说一下,这个问题至少有十年的历史了。 Https://bugzilla.mozilla.org/show_bug.cgi?id=68517.

如能对此作出澄清,我们将不胜感激。无论是从符合标准的角度还是从实用的角度来看。例如,HTTP 客户端库只支持透明的“内容编码”将是一个反对实用性的理由。

94034 次浏览

Quoting Roy T. Fielding, one of the authors of RFC 2616:

changing content-encoding on the fly in an inconsistent manner (neither "never" nor "always) makes it impossible for later requests regarding that content (e.g., PUT or conditional GET) to be handled correctly. This is, of course, why performing on-the-fly content-encoding is a stupid idea, and why I added Transfer-Encoding to HTTP as the proper way to do on-the-fly encoding without changing the resource.

Source: https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31

In other words: Don't do on-the-fly Content-Encoding, use Transfer-Encoding instead!

Edit: That is, unless you want to serve gzipped content to clients that only understand Content-Encoding. Which, unfortunately, seems to be most of them. But be aware that you leave the realms of the spec and might run into issues such as the one mentioned by Fielding as well as others, e.g. when caching proxies are involved.

The correct usage, as defined in RFC 2616 and actually implemented in the wild, is for the client to send an Accept-Encoding request header (the client may specify multiple encodings). The server may then, and only then, encode the response according to the client's supported encodings (if the file data is not already stored in that encoding), indicate in the Content-Encoding response header which encoding is being used. The client can then read data off of the socket based on the Transfer-Encoding (ie, chunked) and then decode it based on the Content-Encoding (ie: gzip).

So, in your case, the client would send an Accept-Encoding: gzip request header, and then the server may decide to compress (if not already) and send a Content-Encoding: gzip and optionally Transfer-Encoding: chunked response header.

And yes, the Transfer-Encoding header can be used in requests, but only for HTTP 1.1, which requires that both client and server implementations support the chunked encoding in both directions.

ETag uniquely identifies the resource data on the server, not the data actually being transmitted. If a given URL resource changes its ETag value, it means the server-side data for that resource has changed.