TL; DR:Chrome将此响应头解释为keep-alive
,并保持持久连接,而Firefox则关闭每个连接。
我在优化我的网站页面加载时间时遇到了这个问题。
在引用的RFC中,我没有找到关于如何正确处理Connection
头中多个条目的任何信息。对我来说,它似乎可以从两种可能性中选择:
- 如果有多个条目,则可以选择最适合您需求的
- 如果包含
close
,则可以在传输后关闭连接
所以,我需要找出答案。让我们进行一些深入的调查:
我注意到Chrome始终使用Connection:keep-alive
发送HTTP / 1.1请求,而我的Apache默认配置始终响应带有Connection:close
头的请求。因此,我开始研究并使用Wireshark查看TCP段。
Chrome需要获取14个元素才能显示该网站,其中大部分是静态内容,如图像或CSS文件。它需要14个TCP连接,并且需要很长时间(大约1.2秒)。在每次请求图像(例如)后,会出现一个设置了FIN
标志为1的TCP段。
那么Chrome与Firefox如何对比呢?Chrome似乎对一个服务器的并发连接数有6个的最大限制。Firefox具有更精细的配置,并区分持久性(最多6个,在about:config中看到)和非持久性(不同来源的最大数字差异很大)。但是等等... Chrome和Firefox都发送带有Connection:keep-alive
的HTTP / 1.1请求头,因此两者都应限制为6个(因为这是请求打开持久连接的方法)。
我决定尝试一个简单的技巧,并将以下行添加到我的web根目录中的.htaccess
文件中:
<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>
服务器现在的响应是:
Connection: keep-alive, close
现在我重新查看了TCP段:Chrome到我的服务器只有9个连接,其中只有3个设置了FIN
标志位。所以这个技巧似乎起作用了。但是为什么会有那3个连接,在数据传输后关闭了连接?这些是PHP请求,因为HTTP头X-Powered-By: PHP/5.4.11
予以确认。
那Firefox呢?还有14个请求!
如何修复并使fcgi进程也支持keep-alive?
我在httpd.conf配置文件的虚拟主机部分添加了以下行:
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100
已经移除了在.htaccess
中添加的部分。现在服务器不再发送任何令人困惑的 - Connection: keep-alive, close
,而是只有Connection: keep-alive
,一切正常运作!
结论:
一个带有连接字段设置为
HTTP/1.1 200 OK
Connection: keep-alive, close
Chrome会将其解释为keep-alive
,而Firefox似乎会关闭每个连接。这似乎取决于实际的实现。
因此,如果您想要处理包含Connection: keep-alive, close
响应标头的客户端实现,我建议尝试使用keep-alive,如果您需要多个请求。最坏的情况是:服务器将关闭连接,您需要重新连接(这正是您本来可以选择的另一个选项!)