为什么浏览器不能发送gzip请求?

71

如果Web服务器可以发送gzip响应,为什么浏览器不能发送gzip请求?

6个回答

66
客户端和服务器必须就通信方式达成一致;其中一部分是通信是否可以压缩。HTTP被设计为请求/响应模型,最初的创建几乎肯定是预计始终有小的请求和潜在的大的响应。压缩不是实现HTTP所必需的,有些服务器和客户端都不支持它。
客户端通过表示它可以支持压缩来实现HTTP压缩,如果服务器在请求中看到并支持压缩,则可以对响应进行压缩。要压缩请求,客户端需要有一个“预请求”,该请求实际上协商了请求将被压缩的方式,或者它必须要求所有请求都支持压缩编码。
*2027年2月更新* 过去8年了,但正如@Phil_1984_指出的那样,第三种可能的解决方案是客户端和服务器协商压缩支持,并在随后的请求中使用它。事实上,像HSTS之类的东西就是这样工作的,客户端缓存了服务器期望仅使用TLS并忽略任何未加密链接的信息。HTTP明确地被设计成无状态的,但我们已经超越了这一点。

那么如果服务器不支持压缩,它会直接失败吗? - jjxtra
2
规范不要求压缩,有些服务器和客户端不支持它。客户端开始说:“嘿,我说法语,你呢?”服务器做出回应,并根据自己是否懂得法语用英语或法语回答。在这个例子中,法语就是压缩。如果像OP所问的那样,客户端能够立即开始用法语交流,所有服务器都必须说法语,否则系统将会崩溃。该系统只允许压缩响应,因为它需要协商并且两个系统都同意。 - Peter Oehlert
1
讲解得非常清楚。通常情况下,没有压缩的小请求会比带有预请求协商的压缩效果更好。 - Ron
1
第三个选项(方便地被忽略了)是让客户端/浏览器记住服务器接受压缩,然后在连接后面发布压缩数据。无论如何,当浏览器连接到服务器时,POST大负载永远不是它的首要任务。 - Phil
1
@Phil_1984_ 我认为历史背景是有帮助的;很容易忘记我们已经走了多远。在1989年,当HTTP被设计成无状态时,486处理器以惊人的20MHz宣布推出,但直到第二年春季才真正可用。互联网还没有真正从连接大学和政府的学术空间中发展出来。无状态在当时是很有道理的。随着代理(浏览器)在过去28年变得更加复杂,增加更多有状态的特性是有意义的,特别是为了实现特定的用例,这也是HSTS的来源。 - Peter Oehlert
显示剩余2条评论

27

客户端无法预先知道服务器是否能理解压缩的请求,但是服务器可以知道客户端可以接受这样的请求。


26
不正确。Content-Encoding是客户端可提供的允许头文件。RFC表示:“如果请求消息中实体的内容编码对原始服务器不可接受,则服务器应该用状态代码415(不支持的媒体类型)进行响应。”- 根据Nick Johnson的说法。 - Pacerier
11
你说的和我想表达的有点不同。你可以像你建议的那样尝试发送一个压缩请求,但是在没有与服务器通信之前,无法提前知道服务器是否会接受它。话虽如此,你的观点很有道理:如果你尝试发送一个压缩请求,你可能会发现服务器支持它。 - Paul Dixon
6
有很多场景你事先就知道服务器支持,比如移动应用与后端通信。 - Guillermo
1
有没有服务器列表实际支持 gzipped 请求? - Eric
有没有任何浏览器可以支持它? - Brady Moritz
压缩通常指表单数据,在这种情况下,客户端将始终知道服务器希望它被压缩,因为服务器提供了请求以该方式进行压缩的表单。 - cnd

7
如果能够保证服务器接受,它是可以的。这可能意味着使用OPTIONS请求。
Web浏览器可以做很多事情(例如,管线化),但它们并没有。Web浏览器开发人员会考虑改变的兼容性影响。
在异构环境中,有很多不同的Web服务器和配置。更改客户端的工作方式可能会破坏其中一些。
也许只有1%的服务器能够接受gzipped请求,但其中一些可能会广告宣传,但不能正确处理-因此用户将无法将文件上传到那些站点。
历史上,有很多破损的客户端/服务器实现-长期以来,在主要Web浏览器中,gzipped响应都是存在问题的(幸运的是现在基本上已经解决)。
因此,你最终会得到一个黑名单的用户代理、服务器(或域名),其中这些选项会自动关闭,这非常糟糕。

3

因为客户端不知道服务器是否接受它。HTTP事务由客户端发送的单个请求和相应组成。客户端发送的其中之一是其支持的编码/压缩方式。服务器可以决定如何压缩响应。但是客户端没有这种选择。


如果服务器能够确定浏览器是否支持它,那么开发人员可以尝试实现一种方案,即浏览器尝试查找服务器是否能够理解g-zipped内容;如果开发人员这样做的话。 - David Refoua
服务器确定浏览器支持gzip是因为浏览器通过Accept-Encoding请求头告诉了它。你需要其他方式让浏览器事先知道服务器的能力。这超出了HTTP/1.1所能提供的范围。 - Yuliy
@Yuliy 你的意思是(例如)使用浏览器内存来记住服务器的Accept-Encoding响应吗? - Phil

2
如果你正在编写一个Web应用程序,我假设你控制着发送给客户端和从客户端发送回来的内容。
在javascript中编写gzip实现很容易,它可以压缩发送到服务器的post数据。服务器可以有一个过滤器(j2ee术语),知道客户端数据是压缩的,这个过滤器会解压缩数据,然后将数据传递给servlet(或Struts中的action类),就像正常读取数据一样,例如request.getParameter(...)。
如果你有控制权,这似乎是完全合理和可行的。正如其他帖子所提到的,你不能依赖浏览器自动完成这个过程,但由于你正在编写Web页面,你可以让浏览器通过一些工作来完成你想要的压缩。
安迪。

0

HTTP是这样设计的:

  • 客户端以纯文本形式发出请求(包括是否能理解压缩响应)
  • 服务器以适当的编码方式进行响应(压缩或非压缩)

但在这种设计中,客户端无法发送压缩请求,因为它不知道服务器是否事先能够理解它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接