先看一张HTTP请求流程图
-
构建请求
浏览器构建请求行信息
GET /index.html HTTP1.1,准备发起请求 -
查询缓存
真正发起请求前,浏览器会先在浏览器缓存中查询是否有要请求的文件。其中,浏览器缓存是一种在本地保存资源副本,以供下次请求时直接使用的技术。
当浏览器发现请求的资源已经在浏览器缓存中存有副本,它会拦截请求,返回该资源的副本,并直接结束请求,而不会再去源服务器重新下载。这样做的好处有:
- 缓解服务器压力,提高性能(获取资源的耗时更短)
- 对于网站来说,缓存是实现快速资源加载的的重要组成部分
当然,如果缓存查找失败,就会进入网络请求过程了。
-
准备IP和端口号
先来说下HTTP和TCP的关系,HTTP作为应用层的协议,用来封装请求的文本信息,并使用TCP/IP传输层协议将请求发送到网络上,所以在HTTP工作之前需要通过TCP协议与服务器建立连接。
下面开始回答问题:
数据包是通过IP地址传输给接收方的,IP是一串数字不好记忆,使用域名好记忆,在发起请求之前需要通过**DNS(Domain Name System域名系统)**将域名转换为IP地址;所以浏览器会请求DNS服务获取到域名对应的IP地址,当然浏览器也提供DNS缓存服务,如果该域名有缓存则直接返回缓存。拿到IP之后就是获取端口号,通常情况下URL没有指定端口号,HTTP协议默认是80端口号
-
等待TCP队列
chrome有个机制,同一域名下同一时间最多许建立6个TCP链接,超出的链接请求将会进入排队等待状态,知道请求中的请求完成。
-
建立TCP连接(Transmission Control Protocol,传输控制协议)
浏览器通过TCP与服务器建立连接,TCP有一下特点:
- 对于数据包丢失的情况,TCP 提供重传机制。
- TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。
- 三次握手确保链接成功,四次挥手确保链接彻底断开
从下图可以看出,一个完整的TCP链接声明周期分为“建立连接”、“传输数据”、“断开连接”三个阶段。
-
建立连接:是指在建立一个 TCP 连接时,客户端和服务器总共要发送三个数据包以确认连接的建立即三次握手
-
传输数据:接收端需要对每个数据包进行确认操作,即接收到数据包之后要向发送端发送接收确认数据包,发送端发出数据包之后再规定时间内没有收到接收端的确认消息则视为数据包丢失,会触发发送端的重发机制,接收端接收到数据包之后,会按照TCP头信息中的序列号进行排序,从而保证组成完整的数据。
-
断开连接:接收端接受完数据包之后就要立即断开连接,要进行四次挥手来确保连接断开
-
发起HTTP请求
- 请求行:首先浏览器会向服务器发送请求行,它包括了请求方法、请求 URI(Uniform Resource Identifier)和 HTTP 版本协议
- 请求体:如果使用 POST 方法,那么浏览器还要准备数据给服务器,这里准备的数据是通过请求体来发送。
- 请求行:在浏览器发送请求行命令之后,还要以请求头形式发送其他一些信息,把浏览器的一些基础信息告诉服务器。比如包含了浏览器所使用的操作系统、浏览器内核等信息,以及当前请求的域名信息、浏览器端的 Cookie 信息,等等。
-
服务器处理并响应请求
- 响应行:包括响应协议版本和状态码
- 响应头:包含了服务器自身的一些信息,比如服务器生成返回数据的时间、返回的数据类型(JSON、HTML、流媒体等类型),以及服务器要在客户端保存的 Cookie 等信息
- 响应体:请求资源的主体内容
- 断开连接:通常情况下,服务器返回数据之后就会立即断开TCP连接,但是如果请求头中设置了
Connention:Keep-Alive,那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度。
以上就是服务器响应浏览器的全过程 重定向 到这来似乎请求流程就要结束了,不过还有一种情况是,比如你在地址栏输入的是baidu.com但是最后打开的是https://www.baidu.com/,前后两个URL不一样是因为涉及到了重定向操作,
从图中可以看出,状态码是301,服务器告诉浏览器要重定向到Location中的地址;不过重定向不是必然的,需要服务器处理重定向跳转。
-
断开TCP连接
- 断开连接:接收端接受完数据包之后就要立即断开连接,要进行四次挥手来确保连接断开
问题解答
-
为什么很多站点第二次打开的速度会很快?
主要是因为浏览器缓存了一些耗时的数据
DNS缓存:在浏览器本地把域名和IP的映射关系缓存起来
页面资源缓存
通过上图总结以下几点:
- 浏览器通过响应头的
Cache-Control来判断是否缓存该资源 - 浏览器通过对
Cache-Control:Max-age=2000中Max-age参数来判断缓存时长 - 资源未过期的情况下,如果再次请求该资源就会直接返回缓存资源
- 缓存过期则会发起求情,并在请求头中加上
If-None-Match:"4f80f-13c-3a1xb12a",服务器会根据该字段来判断该资源是否更新过,没更新则返回304,浏览器直接获取本地缓存;有更新则直接返回新的资源
- 浏览器通过响应头的