要解决这个问题,我们首先要明白问题:HTTP请求能否在一个TCP连接中一起发送(比如3个请求一起发送,3个响应一起接收)?一个TCP连接可以对应多少个HTTP请求?为什么有时不重新建立SSL连接就刷新页面?浏览器是否限制同一主机的TCP连接数?与服务器建立TCP连接后,现代浏览器是否会在建立HTTP请求后断开连接?什么情况下会掉线?第一个问题在与服务器建立TCP连接后,现代浏览器会在HTTP请求完成后断开连接吗?什么情况下会掉线?在HTTP/1.0中,服务器在发送HTTP响应后断开TCP连接。但这样一来,每次请求都会重新建立和断开TCP连接,代价太大。所以虽然标准中没有设置,但是有些服务器支持Connection:keep-aliveheader。意思是完成这个HTTP请求后,不要断开HTTP请求使用的TCP连接。这样做的好处是可以复用连接,后面发送HTTP请求时不需要重新建立TCP连接,而且如果一直保持连接,那么也可以避免SSL的开销。两张图是短时间内两次访问https://www.github.com的时间统计:第一次访问,有初始连接和SSL开销。初始连接和SSL开销消失,表明使用了相同的TCP连接。持久连接:既然维护一个TCP连接有这么多好处,HTTP/1.1就把Connection头写入标准,默认开启持久连接,除非请求指定Connection:close,那么浏览器和浏览器之间的TCP连接服务器会维护一段时间,一个请求结束后不会崩溃。所以第一个问题的答案是:默认情况下建立的TCP连接是不会断开的,只有在请求头中声明了Connection:close才会在请求完成后关闭连接。第二个问题是一个TCP连接可以对应多少个HTTP请求?理解了第一个问题,这个问题就已经有了答案。如果保持连接,一个TCP连接可以发送多个HTTP请求。第三个问题,HTTP请求是否可以在一个TCP连接中一起发送(比如三个请求一起发送,三个响应一起接收)?HTTP/1.1中存在问题。一个TCP连接只能同时处理一个请求,也就是说:两个请求的生命周期不能重叠,任意两个HTTP请求从开始到结束的时间不能在同一个TCP连接中。重叠。虽然在HTTP/1.1规范中指定了Pipelining试图解决这个问题,但是这个特性在浏览器中默认是关闭的。我们先来看看Pipelining是什么。RFC2616规定:支持持久连接的客户端可以“管道化”其请求(即发送多个请求而不等待每个响应)。服务器必须按照接收请求的相同顺序发送对这些请求的响应。支持持久连接的客户端可以在一个连接中发送多个请求(无需等待任何请求的响应)。接收请求的服务器必须按照收到请求的顺序发送响应。至于为什么这样定标准,我们大致可以推测一个原因:由于HTTP/1.1是文本协议,返回的内容无法区分发送的是哪个请求,所以顺序必须一致。比如你向服务器发送了两个请求,GET/query?q=A和GET/query?q=B,服务器返回了两个结果,浏览器没有办法根据响应来判断响应对应的是哪个请求响应结果。Pipelining的想法看起来不错,但在实践中会出现很多问题:一些代理服务器无法正确处理HTTPPipelining。正确的流水线实现很复杂。Head-of-lineBlocking连接头阻塞:建立一个TCP连接后,假设客户端在这个连接中连续向服务器发送了若干次请求。按照标准,服务器应该按照收到请求的先后顺序返回结果。假设服务器花费大量时间处理第一个请求,所有后续请求都需要等待第一个请求结束才能响应。所以现代浏览器默认不启用HTTPPipelining。但是,HTTP2提供了Multiplexing特性,可以在一个TCP连接中同时完成多个HTTP请求。如何实现多路复用是另一个问题。我们可以看看使用HTTP2的效果。绿色是请求发起到请求返回的等待时间,蓝色是响应下载时间。可见都是在同一个Connection中并行完成的,所以这个问题也有了答案:HTTP/1.1中有Pipelining技术可以完成这么多。请求同时发送,但由于浏览器默认关闭它,这可以认为是不可行的。由于HTTP2中多路复用特性的存在,可以在同一个TCP连接中并行执行多个HTTP请求。那么在HTTP/1.1时代,浏览器是如何提高页面加载效率的呢?主要有以下两点:维护与服务器建立的TCP连接,在同一个连接上依次处理多个请求。与服务器建立多个TCP连接。第四个问题为什么有时候刷新页面不需要重新建立SSL连接?第一个问题的讨论中已经有了答案,TCP连接有时会由浏览器和服务器保持一段时间。TCP不需要重新建立,SSL自然会用上一个。问题5:浏览器是否限制同一主机的TCP连接数?假设我们还处在HTTP/1.1时代。那时候还没有复用。当浏览器得到一个有几十张图片的网页时应该怎么办?只打开一个TCP连接顺序下载肯定是不行的,这样用户必须苦苦等待,但是如果每张图片都打开一个TCP连接发送一个HTTP请求,电脑或者服务器可能承受不了。如果有1000张图片,则无法打开。1000个TCP连接,你的电脑不一定同意NAT。所以答案是:是的。Chrome允许最多六个TCP连接到同一主机。不同的浏览器有一些差异。https://developers.google.com/web/tools/chrome-devtools/network/issues#queued-or-stalled-requestsdevelopers.google.com所以回到原来的问题,如果接收到的HTML包含几十个Image标签,以什么方式,以什么顺序,建立了多少个连接,以及使用什么协议来下载这些图像?如果图片都是HTTPS连接,并且在同一个域名下,那么浏览器会在SSL握手后与服务器讨论是否可以使用HTTP2,如果可以的话,使用Multiplexing功能在这个连接上进行多次传输。但是,不一定所有链接到这个域名的资源都会使用TCP连接来获取,但是可以肯定的是,很有可能会用到Multiplexing。如果您发现无法使用HTTP2怎么办?或者你不能使用HTTPS(现实中的HTTP2是在HTTPS上实现的,所以你只能使用HTTP/1.1)。那么浏览器就会在一个HOST上建立多个TCP连接。最大连接数取决于浏览器设置。这些连接在空闲时将被浏览器用来发送新的请求。如果所有连接都发送请求呢?所有其他请求都必须等待。
