HTTP请求过程的详细说明
HTTP协议是基于TCP连接的。它是一种允许浏览器向服务器发送请求以获取资源的协议,是Web的基础。通常浏览器发起请求获取服务器的资源,比如HTML文件、CSS、js文件,除此之外,你还可以获取图片、视频等资源。作为前端开发,了解浏览器使用最广泛的HTTP协议的请求流程非常重要。
一、 浏览器发起HTTP请求的流程
1. 构建请求行
首先,浏览器将基于请求构建请求行信息。请求行由三部分组成:
方法请求的文件路径的HTTP协议版本
获取index.html http 1.1
2. 查找浏览器缓存
在实际发起HTTP请求之前,浏览器将首先检查浏览器的本地缓存中是否有该请求所需的资源。
如果发现浏览器缓存中有这个请求的资源副本,它会拦截这个请求,直接返回缓存中的文件,直接结束这个HTTP请求,不需要再去服务器请求。
如果在浏览器的缓存中找不到资源,将进入网络请求过程。
3. 准备IP地址和端口号(在建立TCP连接之前)
因为浏览器是一个使用HTTP协议作为应用层协议来封装请求的文本信息的软件;并且采用TCP/IP协议作为传输层协议,因此在发起HTTP请求之前必须通过服务器建立TCP连接。TCP协议是一种面向连接的、可靠的、基于字节流的传输协议,也就是说,通过TCP建立连接后,请求行的数据和HTTP构造的请求头必须在TCP的数据传输阶段进行传输。
HTTP协议和TCP协议的关系大致如下:
TCP连接建立阶段
浏览器通过服务器建立TCP连接,三次握手
传输数据阶段
浏览器发送一个HTTP请求,包括请求头、请求行和请求体。
服务器收到请求后,开始处理HTTP请求。
服务器响应HTTP请求,包括返回响应行、响应头和响应体。
TCP断开阶段
浏览器断开TCP与服务器的连接,并挥手四次。
问:HTTP请求的第一步是什么?
正准备与服务器建立TCP连接。
问:建立TCP连接的第一步是什么?
准备目的地的IP地址和端口号,并构造一个TCP报头信息以附加到数据包的报头。
问:我从哪里获得IP地址和端口号?
HTTP在发送请求之前建立TCP连接所需的IP地址和端口号是从请求的URL中获取的。
合法的URL(统一资源定位符)包含请求的协议、域名、端口号、资源路径、哈希、查询参数和其他值。
获取域名,基于DNS(域名系统)服务器查询域名对应的主机IP地址。DNS查询还涉及DNS预解析、浏览器提供的DNS域名缓存服务等。以便更快地确定服务器的IP地址。
至于端口号,一般来说,如果URL中没有指定端口号,那么HTTP协议默认为端口80,HTTPS协议默认为端口443。
4. 等待TCP队列(在建立TCP连接之前)
如果是HTTP1.1版本1.1的请求,需要确认当前请求是否需要排队等待才能建立TCP连接。
Chrome中有一个机制,就是同一个域名最多只能建立6个TCP连接。如果在某个时间同一域名下有10个请求,剩下的4个将在TCP队列中排队,等待该域名下正在进行的域名请求完成后再进入TCP连接。
5. 建立TCP连接
这个过程就是客户端和服务器的三次握手,也就是总共发送三个数据包确认连接的阶段(三次握手的过程后面会详细说明)。
6. 发送HTTP请求
一旦TCP连接成功建立,将进入数据传输阶段。此时浏览器可以与服务器进行通信,在这个通信过程中传输HTTP中的数据。
浏览器将首先向服务器发送构建的请求行信息。请求行的功能是告诉服务器客户端需要什么资源。请求行包含请求的方法、请求的URI和HTTP版本协议。
最常见的请求方法是GET和POST。GET请求一般不需要请求体,而是通过拼接请求URL中的查询参数直接告诉服务器。
POST请求通常用于客户端向服务器提交一些信息,如表单。一般来说,POST请求还需要根据请求体将收集到的数据发送到服务器。
发送请求行后,浏览器会以请求头的形式向服务器发送其他信息。请求头的主要功能是告诉服务器浏览器的一些基本信息,比如:
主机:当前请求的主机域名信息
连接:Keep-alive告诉服务器保持长连接,避免重复三次握手建立tcp连接。
/li>
二、 服务器响应HTTP请求的流程
服务器在接受到客户端请求之后,就会基于请求行和请求头中的信息来准备返回的资源文件。
基于curl -i命令可以查看服务器返回响应的全部数据
curl -i 会获取响应头和响应行以及响应体的全部数据
curl -I 只会获取响应头和响应行,不会获取响应体数据
curl -i https://wht.im/
1. 返回请求
服务器会首先返回响应行信息给客户端
HTTP/1.1 200 OK
响应行信息由三部分组成:HTTP协议版本 响应状态码 对于状态码的描述(关于响应状态码的分类会专门介绍),总之服务器会基于状态码来告诉浏览器本次请求的处理结果。
随后服务器会返回响应头信息给客户端
服务器返回的响应头信息中包含了服务器自身的一些信息:
Server: marco/2.14 服务器信息
Date: Sun, 28 Nov 2021 14:20:22 GMT 服务器生成返回数据的时间
Content-Type: text/html 返回的数据类型
Content-Length: 4340 返回的数据字节长度
Connection: keep-alive 保持TCP长连接
Vary: Accept-Encoding
ETag: "484903b00f89708a70e3f085389563a8"
Last-Modified: Thu, 22 Apr 2021 04:06:04 GMT
Expires: Sun, 28 Nov 2021 14:23:22 GMT
Cache-Control: public, must-revalidate, max-age=180
Accept-Ranges: bytes
最后服务器会返回响应体数据给客户端,响应体中就包含了本次请求所需要的资源文件,浏览器会先从网络进程去下载这个资源,然后将资源提交给渲染进程进行渲染。
2. 断开连接
一般情况下:如果服务器向客户端返回的资源,那么本次请求就到此结束,TCP连接就要关闭。
但是如果浏览器或者服务器的任意一方在其头信息中加入了:Connection:keep-alive的话就代表TCP连接需要继续保持连接状态不要关闭,此时浏览器就可以复用这个TCP连接来传输数据,从而免去重新建立TCP连接所需的时间,从而提高资源加载的速度提升性能。
3. 重定向操作
一般情况下,一次完整的HTTP请求就到此结束了;但是如果服务器返回的状态码是301或者302的话,还涉及一个重定向操作。
如果服务端返回的状态码是301 Moved Permanently,也就是永久重定向,此时浏览器需要重定向到另外一个网址,网址信息就保存在响应头的location字段中,并用该地址重新进行导航。
问题汇总
问题一:为什么有些站点第一次打开很慢,当再次访问这个站点的时候速度很快
这是因为在第一次请求的过程中,浏览器将请求的资源数据缓存在了本地。当第二次请求的时候,很多资源都不需要重新发起请求去获取而是直接从本地缓存的资源副本加载,这中间省去了进行网络请求所消耗的时间;除此之外,还有一个重要因素就是浏览器也会讲DNS查询记录缓存在本地,也减少了DNS解析所消耗的时间。
服务器是通过什么方式让浏览器缓存数据的
第一次请求的时候,服务器会在HTTP的响应头中通过Cache-Control字段来设置是否需要缓存该资源。
一般情况下,我们需要为这个资源设置缓存过期的时长,而这个时长就是通过Max-age值参数设置的,注意单位是s,不是ms。
Cache-Control:Max-age=1024;
代表着本次服务器返回的资源需要缓存,并且在浏览器本地缓存的时间是1024秒
- 如果缓存资源没有过去那么再次请求就会拦截该请求并直接返回缓存中的资源给浏览器
- 如果缓存过期了,那么浏览器会继续发起新的HTTP请求,并且在请求头中加上:
If-None-Macth:'4f80f-13c-3a1xb12a';
服务器收到请求之后,会根据If-None-Macth字段的值来判断本次请求的资源来服务器上是否有更新:
-
如果没有更新,那么就返回状态码304 Not Modified,告诉浏览器本次请求的资源在服务器没有发生过更新,你可以继续使用之前的缓存资源副本,这次就不再返回新的数据了。
-
如果已经发生了更新,就将最新的资源返回给客户端。
问题二:为什么登录过一个网站之后,下次再访问的时候就不需要重新登录而已经是登录态了
- 服务端在接受到浏览器提交的用户登录信息之后,查询后台数据库并验证用户身份是否正确,如果正确的话会生成一段表示用户身份的字符串,并将该字符串参数写入到响应头的Set-Cookie字段中,然后将该信息响应给浏览器。
Set-Cookie:UID=159842301;
-
浏览器接受到响应头并解析,如果响应头中包含了Set-Cookie字段,那么浏览器就会将该字段中的信息保存到本地,cookie是浏览器本地存储的一种方案,有专门的js方法对其进行读写操作。
-
当第二次用户再次访问该网站的时候,在发起请求之前浏览器会读取之间存储在本地的cookie信息,并把数据写入到本次请求头的Cookie字段中提交给服务器。
Cookie:UID=159842301;
- 服务器在接受到请求之后,解析请求头信息中的Cookie字段之后,获取到UID=159842301的信息之后,服务器查询数据库来判断该用户是否为已登录状态,如果查询正确就直接返回包含该用户信息的数据给浏览器,就不用重新进行登录了。
问题三:如果一个页面的网络加载时间过久,你是如何分析卡在哪个阶段的
最好的方法是基于Network面板下的Timing来来进行分析。
Timing表示该请求的时间线轴线:
-
Quened at 36.01ms
代表发送请求前的排队所消耗时间为36.01ms
有可能是前面有正在发送的请求
有可能是有的请求优先级比较高所以排队(network中有Priority选项代表请求的优先级)Started at 36.01ms
正式开启请求时间 -
Connection Start 开始连接
Stalled tcp链接复用 处理代理相关的逻辑所等待的时间
DNS Lookup DNS域名解析消耗的时间
Initial connection 创建TCP连接所消耗的时间
SSL HTTPS请求进行SSL协商消耗的时间 -
Request/Response 请求响应阶段
Request sent 发送请求的时间 很短 没法优化
Waiting(TTFB)从发起请求到服务器返回首字节时间(可优化点:请求发出到响应总时长)
Content Download 服务器返回的资源下载所需时间(可优化点:返回资源的大小会影响时间)
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/132074.html