从输入URL到页面呈现

这是一个宽泛的命题,仅记录主要步骤。

  • 分析URL合法性,构造请求
  • 查找强缓存
  • DNS 解析
  • TCP 连接
  • 发送 HTTP/HTTPS 请求
  • 页面渲染
  • 视情况关闭 TCP 连接

一、分析URL合法性,构造请求

浏览器会检查URL,不正常的URL会显示错误页面或者直接使用搜索引擎搜索,合法的URL会正常构造一个请求。

二、查找强缓存

浏览器直接先在本地缓存找是否有资源。

强缓存详见链接

三、DNS 解析

  1. 将请求发送到本地 DNS 服务器中,本地 DNS 服务器会判断是否存在该域名的缓存,如果不存在,则向根域名服务器发送一个请求。
  2. 从“根域名服务器”查到“顶级域名服务器”的 NS(Name Server) 记录和 A 记录( IP 地址)。
  3. 从“顶级域名服务器”查到“次级域名服务器”的 NS 记录和 A 记录( IP 地址)。
  4. 从“次级域名服务器”查出“主机名”的 IP 地址。

向本地 DNS 服务器发送请求的方式就是递归查询,因为只需要发出一次请求,然后本地 DNS 服务器返回给我们最终的请求结果。而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询,因为每一次域名服务器只返回单次查询的结果,下一级的查询由本地 DNS 服务器自己进行。

四、TCP 连接

第一次握手,客户端向服务器发送一个 SYN 报文段,SYN 置为1,序号字段 seq 是一个随机数。

第二次握手,服务器端接收到客户端发送的 SYN 连接请求报文段后,服务器首先会为该连接分配 TCP 缓存和变量,然后向客户端发送 SYN ACK 报文段,SYN 和 ACK 置为 1,还有序号字段是服务器端产生的一个随机数。确认号字段为客户端发送的序号加一。

第三次握手,客户端接收响应后,也会为这次 TCP 连接分配缓存和变量,同时向服务器端发送 ACK 报文段,ACK 置为1,序号字段为第二次握手时的确认号,确认后字段为第二次握手时的序号。第三次握手可以在报文段中携带数据。

image-20200622151722927

五、发送请求

请求行、请求头和请求体。

详见链接

如果是HTTPS,则要经过TLS加密:

  1. 第一步,客户端向服务器发起请求,请求中包含使用的协议版本号、生成的一个随机数、以及客户端支持的加密方法

  2. 第二步,服务器端接收到请求后,确认双方使用的加密方法、并给出服务器的证书、以及一个服务器生成的随机数

  3. 第三步,客户端确认服务器证书有效后,生成一个新的随机数,并使用数字证书中的公钥,加密这个随机数,然后发给服务器。并且还会提供一个前面所有内容的 hash 值,用来供服务器检验。

  4. 第四步,服务器使用自己的私钥,来解密客户端发送过来的随机数。并提供前面所有内容的 hash 值来供客户端检验。

  5. 第五步,客户端和服务器端根据约定的加密方法使用前面的三个随机数,生成对话秘钥,以后的对话过程都使用这个秘钥来加密信息。

六、页面渲染

  • 解析 HTML 代码构建 DOM 树,解析 CSS 代码构建 CSSOM 规则树;
  • 根据 DOM 和 CSSOM 构建 Render Tree ;
  • 利用 Render Tree 对页面进行布局和绘制,最后显示;

关于阻塞:在解析 HTML 代码时,遇到 <script> 浏览器会先下载和构建CSSOM,然后执行脚本,最后才是继续构建DOM。

defer 和 async的区别

七、关闭TCP连接

如果请求头或响应头中包含Connection: Keep-Alive,表示建立持久连接,这样TCP连接会一直保持,之后请求统一站点的资源会复用这个连接,否则断开TCP连接。

第一次挥手,客户端向服务器发送一个 FIN 报文段,申请断开连接,FIN 置为1,序列号字段是一个随机数。发送后客户端进入 FIN_WAIT_1 状态。

第二次挥手,服务器端接收到请求后,向客户端发送 ACK 报文段,序列号字段是一个新的随机数,确认号字段是第一次挥手时序列号加1。因为连接是全双工的,所以此时服务器端还可以向客户端发送数据。服务器端进入 CLOSE_WAIT 状态。客户端收到确认后,进入 FIN_WAIT_2 状态。

第三次挥手,服务器端发送完所有数据后,向客户端发送 FIN ACK 报文段,序列号字段是一个新的随机数,确认号字段与第二次挥手时一样。发送后进入 LAST_ACK 状态。

第四次挥手,客户端向服务器端发送 ACK 报文段,序列号字段是第三次挥手时的确认号,确认号字段是第三次挥手时的序列号加1,并进入 TIME_WAIT 阶段。该阶段会持续2MSL,即该报文段在网络中的最大生存时间。如果该时间内服务端没有重发请求的话,客户端进入 CLOSED 的状态;如果收到服务器的重发请求就重新发送 ACK 报文段。服务器端收 ACK 报文段后就进入 CLOSED 状态。

image-20200622152454502

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

浏览器存储方式 Previous
Vue源码笔记 Next