关于GET请求会发送几次这个问题,总结起来主要有以下几点:
-
正常情况下,浏览器发起一个GET请求,服务器返回响应,这个请求就完成了,只会发送一次。
-
但是如果请求过程中出现网络问题导致请求超时,浏览器可能会重试发送这个请求。许多浏览器的默认重试次数是3次,也就是最多会发送4次请求。
-
如果页面有重定向的情况,也会导致发送多个请求。比如A页面重定向到B页面,会先发送A页面的请求,收到重定向响应后再发送B页面的请求。
-
如果页面中链接到了其他域名的资源,如引用了第三方CDN的JavaScript文件,这也会产生额外的GET请求。
-
对于一些特殊资源,浏览器也可能会定期主动重新获取,以确保内容更新。比如获取新的favicon图标等。
-
使用了HTTP persistent connection的情况下,多个请求会复用同一个TCP连接,这时请求计数也会更复杂。
-
获取相同URL资源的请求,浏览器也可能从缓存中直接读取而不用重新发请求。
所以综合来说,一个页面到最终全部加载完成,会产生多个GET请求,具体次数取决于页面复杂程度。但正常情况下每个URL的资源,浏览器Attempt一个新的GET请求的次数是有限制的,一般不会超过3-5次。
为什么使用了HTTP persistent connection的情况下,多个请求会复用同一个TCP连接,这时请求计数也会更复杂。怎么更复杂了,举例说明?
使用HTTP持久连接后的请求计数更复杂主要体现在以下几个方面:
- 一个TCP连接上可以携带多个HTTP请求/响应,不再是一一对应的。
举例:
不使用持久连接:
- TCP连接1: GET页面A
- TCP连接2: GET CSS文件
- TCP连接3: GET图片文件
使用持久连接:
- TCP连接1: GET页面A, GET CSS文件, GET图片文件
- 浏览器和服务器端的请求计数可能不一致。
浏览器端可能考虑重试了两次页面A的请求,一共请求了3次。
但服务器端只收到客户端通过持久连接送过来的1次页面A请求。
- 对于同一个资源的后续请求,可能会直接从浏览器缓存取数据,不会发出请求。
举例:
- TCP连接1: GET页面A
- TCP连接1: GET CSS文件
- TCP连接1: GET图片文件
- TCP连接1: GET图片文件(从缓存取)
浏览器会考虑它请求了4次,但服务器只收到3次请求。
- 在pipeline机制下,多个请求可能会并行被发送出去,响应也可能乱序到达,请求和响应不再是顺序一一对应的。
所以使用了持久连接后,从网络层面很难仅根据请求和响应次数推测出浏览器端的确切请求计数和顺序。需要综合考虑缓存、重试等多方面因素。这就使得请求计数变得更加复杂。