# 浏览器页面呈现过程
在本文中,我们介绍从输入链接到浏览器呈现页面的过程中,浏览器所经历的基本流程。
## DNS解析
首先浏览器将输入的链接进行`DNS`解析,也就是将域名转换为`IP`地址的过程,得到了服务器具体的`IP`地址,才可以进行`TCP`链接以及数据的传输,具体`DNS`解析的过程为:
- 浏览器首先检查自身的`DNS`缓存是否对于此域名有`IP`地址,`chrome`对于域名解析的缓存时间为`60s`,可以通过地址栏输入`chrome://net-internals/#dns`清除`DNS`缓存。
- 若浏览器解析缓存未命中,则到操作系统中`hosts`文件检查域名与`IP`对应关系。若`hosts`文件未命中,则向本地域名服务器请求解析,本地域名服务器一般是运营商`ISP`提供的,一般是通过`53`端口发送`UDP`报文请求服务器解析`DNS`。
- 若本地服务器解析未命中则会有两种解析方案: 迭代解析与递归解析。一般来说,主机向本地域名服务器的查询一般都是采用递归查询,本地域名服务器向根域名服务器的查询通常是采用迭代查询,依次向根域名服务器、顶级域名服务器、主域名服务器等一级一级查询查询直到查询到`IP`地址。
## TCP三次握手
`HTTP`协议是使用`TCP`协议作为其传输层协议的,在拿到服务器的`IP`地址后,客户端浏览器会与服务器建立`TCP`连接,该过程包括三次握手。
```
client server
主动打开 → SYN=1,seq=x → 被动打开,接收
(同步已发送) (同步收到)
接收 ← SYN=1,ACK=1,seq=y,ack=x+1 ← 发送
(已建立链接) (同步收到)
发送 → ACK=1,seq=x+1,ack=y+1 → 接收
(已建立链接) (已建立链接)
```
1. 第一次握手:客户端主动链接服务器,发送初始序列号`seq=x`与`SYN=1`同步请求标志,并进入同步已发送`SYN_SENT`状态,等待服务器确认。
2. 第二次握手:服务端收到消息后发送确认标志`ACK=1`与同步请求标志`SYN=1`,发送自己的序列号`seq=y`以及客户端确认序号`ack=x+1`,此时服务器进入同步收到`SYN_RECV`状态。
3. 第三次握手:客户端收到消息后发送确认标志`ACK=1`,发送自己的序列号`seq=x+1`与服务器确认号`ack=y+1`,发送过后即确认链接已建立状态`ESTABLISHED`,服务端接收确认信息后进入链接已建立状态`ESTABLISHED`。
## SSL加密传输
`SSL`的建立是为了`HTTPS`加密传输,`HTTPS`在`HTTP`的基础下加入`SSL`层,`HTTPS`的安全基础是`SSL`,因此加密的详细内容就需要`SSL`。
1. 首先`TCP`三次握手建立链接,这是数据传输基础,在此之上开始`SSL`。
2. 客户端首先发送`Client Hello`开始`SSL`通信,报文中包含客户端支持的`SSL`版本、随机值`Random1`、加密算法以及密钥长度等。
3. 服务器发送`Server Hello`,和客户端一样,在报文中包含`SSL`版本、随机值`Random2`以及加密组件,此后服务端将证书也发送到客户端。
4. 此时客户端需要对服务端发送的证书进行验证,通过操作系统内置的`CA`证书,将服务器发送的证书的数字签名进行解密,并将证书的公钥进行相同算法的`HASH`与解密的数字签名解密的内容进行对比,验证证书是否合法有效,是否被劫持更换。
5. 客户端验证证书合法,然后生成一个随机值`Random3`,用公钥对`Random3`进行加密,生成`Pre-Master Key`,客户端以`Client Key Exchange`报文将`Pre-Master Key`发送到服务端,此后发送`Change Cipher Spec`报文表示此后数据传输进行加密传输。
6. 服务端将`Pre-Master Key`用自己的私钥解密为`Random3`,服务端发送`Change Cipher Spec`报文表示此后数据传输进行加密传输。
7. 此时客户端与服务端都拥有三个随机字符串,且`Random3`是密文传输的,是安全状态的,此时则可以使用这三个字符串进行对称加密传输。由于非对称加密慢,不能每次传输数据都进行非对称加密,所以使用非对称加密将密钥协商好然后使用对称加密进行数据传输。
8. 此时便正常进行`HTTP`数据传输,但是由于`SSL`加密的作用,此时的`HTTP`传输便是安全的,此为`HTTPS`的传输过程,其中`2`、`3`、`5`、`6`也被称为`SSL`四次握手。
## 发起请求
浏览器构建`HTTP`请求报文,并通过`TCP`协议传送到服务器的指定端口,`HTTP`请求报文一共有三个部分,报文首部,通常包含请求行与各种请求头字段等;空行,告诉服务器请求头部到此为止),报文主体,即发送的数据信息,通常并不一定要有报文主体。
```
GET / HTTP/1.1
accept: text/html
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
...
u=1&t=1587699008
```
## 响应报文
服务端响应`HTTP`请求,返回响应报文,`HTTP`响应报文由四部分组成:响应行、响应头、空行、响应体。
```
HTTP/1.1 200 OK
content-encoding: gzip
content-type: text/html; charset=utf-8
date: Fri, 24 Apr 2020 03:34:50 GMT
...
{"status":1, "msg": "success"}
```
## 浏览器渲染页面
1. 自上而下,首先解析`HTML`标签,生成`DOM Tree`
2. 在解析到``或者`