最近部门组织了一次前端性能优化交流会,大家从输入页面 URL 到最终页面展示内容这个过程提出了许多优化点。但同时发现很多同学对 HTTP 协议层的知识不能串联起来,于是整理了这篇文章,希望可以给大家带来一丝灵感。
当我们在页面上发起一个 AJAX 请求的时候,在网络协议层面都经历了哪些内容?
// 发起请求
fetch('https://baidu.com')
// 协议层1...
// 协议层2...
// 协议层3...
.then(res=>
// 得到结果
console.log(res)
})
如上述代码所示,我们对 baidu.com
发起了一个网络请求,最终在 then 方法中得到了具体的响应内容。
使用 Wireshark 抓包结果如下:
图中可以看到,请求 baidu.com 时,首先通过 TCP 3 次握手建立连接,然后通过 HTTP 传输内容,最后通过 TCP 4 次挥手断开连接。
真实的过程更加复杂,我们主要分析以下几点:
- 建立连接阶段
- DNS 域名解析(应用层)
- 建立 TCP 连接(传输层)
- 通过 IP 寻址找到目标服务器(网络层)
- 通过 Mac 寻址找到服务器硬件接口(数据链路层)
- 通过网线向服务器硬件接口传输比特信息(物理层)
- 发送数据阶段
- 建立 SSL 安全连接(传输层)
- 发送 HTTP 请求(应用层)
建立连接阶段
要获取 baidu.com 的网页内容,就需要和 baidu 服务器建立连接,怎样建立这个连接呢?
- 通过 DNS 获取 baidu 的 IP 地址。
- 建立 TCP 连接。
DNS 域名解析
通过 DNS 解析,我们就能找到 baidu 服务器对应的 IP 地址。
如图:
经过 DNS 解析后,我们就能得到 baidu.com 的 IP 地址了:39.156.69.79 和 220.181.38.148,通常客户端会随机选中一个 IP 地址进行通信。
域名的解析步骤
其实 IP 不一定要通过 DNS 解析才能获取,它通常会被客户端缓存,只有在 DNS 缓存都没有命中的时候才会请求 DNS 服务器。
判断步骤如下:
- 判断浏览器是否有缓存 IP 地址。
- 判断本机是否有缓存该 IP 地址,如:检查 Host 文件。
- 判断本地域名解析服务器是否有缓存 IP 地址,如:电信,联通等运营商。
- 向 DNS 根域名解析服务器,解析域名 IP 地址。
- 向 DNS