当一个 URL 被敲进浏览器地址栏,会发生什么?这个问题回答起来不难,但是想讲清楚却不容易。
引子
当一个 URL 被敲进浏览器地址栏,会发生什么?这个问题回答起来不难,但是想讲清楚却不容易。
最近面试的时候也有很多次被问到,总结一下,当然下文中也不是很全面,其中提到的一些知识点,还需要诸君自己探索。
很多时候被问问题不管什么问题,都有人觉得这玩意没什么讲的,这也需要讲?简简单单讲完了,自以为讲明白了。这里面一个很大的逻辑问题就是,你默认自己讲的就是标准答案了所以看到别人的面经会产生上边的疑问,实际上尽可能得多讲都不一定达到面试官想要的效果。笔者虽然面试经历不是很多,但大多数面试官对基础表示认可,有时间会写写自以为的面试经验。
流程
在打开网页过程中,较为简单的网页会直接发起请求并加载,有些较为复杂或者做过优化的网页,可能会有两种情况:
- HTML 页面加载
- 网页静态资源的加载
下面是结合了一些博客之后总结下来的。
1. 大概流程
1 | st=>start: 开始 |
2. 页面加载具体分析
2.1 DNS 解析
输入 URL 之后,通常浏览器会进行 URL 解析,URL,例如 https://tyzhang.top/posts/
一般包括几大部分:
- Protocol:协议头,例如,HTTP、HTTPS、FTP 等。
- Host:主机域名或者直接是 IP 地址。
- Port:端口号,一般都省略了,比如 80、8080、443。
- Path:要访问的目录在网站的路径。
解析完成后就要去进行 DNS 解析。何为 DNS 解析,网络中的主机都是使用 IP 地址来标识的,即 IP 地址才是主机在网络中的位置。域名只是为了方便记忆使用的。比如,我们访问 taobao.com,要比访问它的 IP 地址容易得多,毕竟我们根本记不住那么多的 IP 地址。这也是为什么较短的域名比较值钱的原因。像早先罗永浩的锤子手机因为 LOGO 是个锤子 T 所以注册了 t.tt
。我们接着看 DNS 的解析,解析遵循先己后他,由近到远的原则进行:
-
浏览器拿到地址会首先搜索浏览器自身缓存的 DNS 记录,例如 Chrome 可以通过
chrome://net-internals/#dns
查看。 -
如果浏览器缓存中没有找到,则去查看 HOSTS 文件和操作系统的缓存。
- 操作系统缓存,Windows 下可以使用
ipconfig /displaydns
查看。 - 其次在系统的指定位置,可以查看 HOSTS 文件,里面记录了域名和 IP 的对应结果。我们可以通过修改此文件的内容,更改映射关系,从而科学上网。
- 操作系统缓存,Windows 下可以使用
-
如果 2 中的操作没有找到,就向域名服务器发送请求。
当前两步都没有命中的时候,开始向 DNS 服务器发送请求,即平时设置中填写的那个 DNS 服务器。这时候才算真正意义上的解析流程开始。一般用户都会去使用附近的域名解析服务器。
-
如果域名服务器也没有记录,开始递归 + 迭代解析。
先看一个架构图:
1
2
3
4
5
6
7
8graph TD
top(根域服务器) --- l11(.com 域服务器)
top(根域服务器) --- l13(...)
top(根域服务器) --- l12(.cn 域服务器)
l11(.com域服务器) --- l21(google.com 服务器)
l11(.com域服务器) --- l22(...)
l21(google.com 服务器) --- l31(mail.google.com 服务器)
l21(google.com 服务器) --- l32(...)-
首先我们的域名解析服务器会向根域服务器(全球只有 13 台)发出请求。显然,仅凭 13 台服务器不可能把全球所有IP都记录下来。所以根域服务器记录的是 com 域服务器的 IP、cn 域服务器的 IP、org 域服务器的 IP。如果我们要查找 .com 结尾的域名,那么我们可以到 com 域服务器去进一步解析。所以其实这部分的域名解析过程是一个树形的搜索过程。
-
根域服务器告诉我们 com 域服务器的 IP。接着我们的域名解析服务器会向 com 域服务器发出请求。根域服务器并没有mail.google.com 的 IP,但是却有 google.com 域服务器的 IP。接着我们的域名解析服务器会向 google.com 域服务器发出请求。如此重复,直到获得 mail.google.com 的 IP 地址。
为什么是递归:问题由一开始的本机要解析 mail.google.com 变成域名解析服务器要解析 mail.google.com,这是递归。
为什么是迭代:问题由向根域服务器发出请求变成向 com 域服务器发出请求再变成向 google.com 域发出请求,这是迭代。
-
-
获取域名对应的 IP 后,一步步向上返回,直到返回给浏览器。
2.2 发起 TCP 请求
浏览器会选择一个大于1024的本机端口向目标 IP 地址的 80 端口发起 TCP 连接请求。经过标准的 TCP 握手流程,建立 TCP 连接。这一部分就不再赘述,大家都是老建立链接了。
2.3 发起 HTTP 请求
流程:请求 -> 请求报文 -> 响应报文 -> HTML 解析,构建 DOM 树 -> 静态资源加载
构建 HTTP 请求报文并通过 TCP 协议发送到服务器指定端口。
HTTP 请求报文是由三部分组成的,请求行、请求报头和请求正文。
请求行:常用方法有 GET, POST, PUT, DELETE, OPTIONS, HEAD。
补充:POST 和 GET 的区别。
请求报头:允许客户端向服务器传递请求的附加信息和客户端自身的信息。
请求正文:当使用 POST, PUT 等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 现在的 Web 应用通常采用 Rest 架构,请求的数据格式一般为 json。这时就需要设置 Content-Type: application/json。
服务器处理请求并返回 HTTP 报文。HTTP 响应报文也是由三部分组成:状态码,、响应报头和响应报文。
状态码
- 1xx 【消息】服务器收到请求,需要请求者继续执行操作
- 2xx 【成功】请求已成功被服务器接收、理解、并接受。
- 3xx 【重定向】客户端需要采取进一步的操作以完成请求
- 4xx 【客户端请求错误】客户端错误,请求包含语法错误或无法完成请求
- 5xx 【服务器错误】服务器在处理请求的过程中发生了错误
HTTPS
这里面会牵扯一些诸如 HTTP 和 HTTPS,HTTP 各个版本的差异,这里简单写一下。
简单来讲,HTTPS 和 HTTP 区别就是 HTTPS 会建立 SSL 链接,保证接下来的通信都是加密的,无法被截取分析。下面简述一下 SSL 握手过程。
- 浏览器请求建立 SSL 链接,并向服务端发送一个随机数 A 和客户端支持的加密方法,比如 RSA 加密,此时是明文传输。
- 服务器从中选出一组加密算法和 Hash 算法,回复一个随机数 B,并将自己的身份信息以证书的形式发回给浏览器。证书中包含了网站地址、非对称加密公钥以及证书颁发机构等信息。
- 浏览器收到服务器的证书之后:
- 验证证书的合法性。
- 用户接收证书之后,浏览器会产生新的随机数 C,然后使用证书中的公钥以及指定的加密方法加密 C 发给服务器。
- 利用 ABC 通过一定的算法生成 HTTP 链接数据传输的对称加密 Key。
- 使用约定好的 Hash 算法计算握手信息,并且使用生成的 Key 对消息进行加密,最后将之前生成的所有信息发送给服务端。
- 服务器端操作:
- 利用已知加解密方式与自己的私钥进行解密,获取 C。
- 和浏览器相同规则生成 Key。
- 使用 Key 解密浏览器握手消息,并验证 Hash 是否一致。
- 使用 Key 加密一段握手消息发送给浏览器。
- 浏览器节米并计算握手消息的 Hash 值,如果和服务器发来的 Hash 值一致,握手结束。
- 此后都使用 Key 进行对称加密。
请求到请求被服务器接收
- 在应用层发送http请求;DNS 解析 IP 发送 HTTP 请求
- 到传输层通过三次握手建立 TCP/IP 连接;UDP
- 到网络层的IP寻址;IP 和 ARP
- 到数据链路层的封装成帧;
- 到物理层的利用物理介质传输;
2.4 四次挥手结束
3. 静态资源加载
什么是 CDN?如果我在山东访问杭州的淘宝网,跨省的通信必然造成延迟。如果淘宝网能在广东建立一个服务器,静态资源我可以直接从就近的广东服务器获取,必然能提高整个网站的打开速度,这就是 CDN。CDN 叫内容分发网络,是依靠部署在各地的边缘服务器,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度。