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

Eug*_*sky 90 gzip http content-encoding transfer-encoding

关于是否要做什么,目前的情况如何

Transfer-Encoding: gzip
Run Code Online (Sandbox Code Playgroud)

或者a

Content-Encoding: gzip
Run Code Online (Sandbox Code Playgroud)

当我想允许具有有限带宽的客户端表示他们愿意接受压缩响应并且服务器具有最终决定是否压缩时.

后者就是例如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).并且没有理由在这种情况下触摸VaryETag任何其他标题,因为它是传输级别的东西.

现在我不太关心"逐跳"的问题Transfer-Encoding,其他人似乎首先关注的是,因为代理可能会解压缩并向客户端转发未压缩的东西.但是,如果原始请求具有正确的Accept-Encoding标头,则代理可能也可以原样转发(压缩),如果所有浏览器都知道给定的话.

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

任何有关这方面的澄清将不胜感激.无论是在符合标准的还是被认为是实用的方面.例如,仅支持透明"内容编码"的HTTP客户端库将成为反对实用性的论据.

Eug*_*sky 34

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

以不一致的方式动态改变内容编码(既不"从不"也不"总是")使得以后关于该内容的请求(例如,PUT或条件GET)无法正确处理.这当然是为什么要执行动态内容编码是一个愚蠢的想法,为什么我将Transfer-Encoding添加到HTTP作为在不改变资源的情况下进行动态编码的正确方法.

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

换句话说:不要进行即时内容编码,而是使用Transfer-Encoding!

编辑:即,除非您想将gzip压缩内容提供给只了解Content-Encoding的客户端.遗憾的是,这似乎是其中的大多数.但请注意,您离开了规范的领域,可能遇到诸如Fielding以及其他人提到的问题,例如涉及缓存代理时.

  • @KemHeyndels关于对.换句话说:**根据规范,Transfer-Encoding是纯粹的_transport layer_ detail**,即中间代理可以自由撤消,例如在该级别的gzip压缩,**而Content-Encoding是_business layer_ property**,除了其他分支(ETag等)之外,不允许代理更改.**根据现实**,TE通常不用于压缩,许多服务器/客户端甚至不支持开箱即用,而**CE或多或少地使用TE的意图使用**:作为_transport layer_ detail. (26认同)
  • @KemHeyndels理想主义者必须首先向所有开源HTTP客户端/服务器实现添加TE支持.然后让自己受雇于每个拥有闭源HTTP实现的公司(我认为无论如何都是微软)并在那里添加功能.在那之后,现实和规范将重合.;)(并且HTTP 2.0已经发布,无论如何都会让问题消失) (11认同)
  • 表明您支持Transfer-Encoding仍然无法明确表示您支持gzip over Transfer-Encoding,因此不会为您带来任何收益.**指示是以相反的方式完成**:任何可以通过Transfer-Encoding进行gzip的客户端都可以通过设置`TE:gzip`来让服务器知道.然后您的服务器应该转移传输编码路由.如果客户端只说"Accept-Encoding:gzip",则必须使用`Content-Encoding`方式.如果客户端既未在其请求中指定,则服务器也不能进行gzip. (9认同)
  • 因此,如果我做对了:1.内容编码是指摘要中服务器上的内容编码,即服务器将以指定的编码一致地提供内容.2.传输编码是指服务器决定用于在此实例中将其传递给用户代理的编码,即在此响应中.只是确保我没有误解你的答案. (2认同)
  • @CMCDragonkai不知道为什么你问一个关于“分块”传输编码的问题作为对“传输”与“内容”编码的答案的评论,但无论如何:“分块”将任意字节流分块成“字节流”块”(任意大小)。这里的关键字是“任意字节”。Chunker 和 dechunker 既不知道也不关心字节的内容,字节可以是任何二进制格式,如 jpeg,如果在文本中,它很可能包含表示 CR / NL 的字节序列。如果你想确切地知道它是如何工作的,请提出一个问题。 (2认同)

Rem*_*eau 27

正如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值,则表示该资源的服务器端数据已更改.

  • [内容编码是Request-URI标识的实体的特征](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11)换句话说:**不同` Content-Encoding`需要不同的`ETag`**这是什么[mod_deflate bug](https://issues.apache.org/bugzilla/show_bug.cgi?id=39727)我在我的回答中提到的是关于.让我想知道为什么这个应用程序级细节首先在HTTP标准中.当使用`Transfer-Encoding`,传输级别设置时,不需要更改`ETag`.除了没人实施Transfer-Enc. (13认同)
  • 内容编码不适用于“动态”编码。RFC 2616 说“传输编码......与内容编码的不同之处在于传输编码是消息的属性,而不是实体的属性。”(https://tools.ietf.org/html/rfc2616 #section-14.41),以及“内容编码是由请求 URI 标识的实体的特征。通常,实体正文与此编码一起存储”(https://tools.ietf.org/html/ rfc2616#section-14.11)。所以我投了反对票。 (3认同)