一杯奶茶的时间了解url到页面渲染发生了什么?

337 阅读9分钟

了解从url到页面渲染发生了什么可以让我们完善前端知识体系,之前一直是模模糊糊的,所以今天花一些时间来总结一下具体流程,也有利于自己整个体系的搭建,觉得总结的有问题还请大家纠正指点。

六个过程

简单来说,分为六个过程:

  1. DNS解析:将域名地址解析为IP地址
  2. TCP三次握手
  3. 发送请求
  4. 接受响应
  5. 渲染页面
  6. TCP四次挥手

接下来看看具体的细节

DNS域名解析

DNS域名解析就是解析域名对应的IP地址或者是IP对应的域名,比如要访问 这个域名,首先电脑会去DNS服务器中查询 这个域名对应的 IP 地址是 129.42.38.1 ,然后通过IP就可以访问了。

但实际上我只是知其然而不知其所以然,比如一个域名是www.bilibili.com, 他实际上是真正的域名应该是(www.bilibili.com.) ,在域名的最后面也有一个 . (点), 域名都是由(.)来划分的,所以域名的最后也需要有一个点来划分,但是因为最后都是由根来统一管理,像我们熟知的 (.com .cn .edn .net)都是由最后一个根来管理的,所以就没有必要在最后面全部加一个.root,所以直接用 . 来表示,而一般我们都会把这个点忽略掉,这样我们就完成了域名树的结构:

image.png

实际上这个跟也是由一群服务器组成的,但是这群服务器只用了仅仅13个域名(从a到m),这13个根域名是由12个独立机构营运的。(目前由12个独立机构运营的跟服务区已经有1467个节点),一样的ip地址,那我们如何与最近一个节点取得联系呢?是通过哪种技术实现的呢?答案就是采用任播这种技术,当我们向根域名服务器进行联系时,就能找到离我们最近的根域名服务器,那么,根域名服务器会管理(.com .cn .edn .net)这些服务器,这些服务器称为顶级域名服务器,顶级域名服务器会管理各自的域名服务器,比如刚刚说的(bilibili, baidu, qq),也叫权威域名服务器,权威域名服务器机会管理各自的主机,当然,实际网络中的管理层会更复杂,不过万变不离其宗。

image.png 这样我们就知道了DNS的大概内容,但是每一次DNS域名解析都要花费大量的时间,所以需要优化DNS域名解析,DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种:

浏览器缓存 (如果有直接使用,没有进入下一阶段)
系统缓存   (如果有直接使用,没有进入下一阶段)
路由器缓存 (如果有直接使用,没有进入下一阶段)
IPS服务器缓存 网络运营商缓存 (如果有直接使用,如果没有那就进入递归搜索)

如果上面四种都没有缓存的话,就会进入递归搜索

- 递归(迭代)搜索: blog.baidu.com
                    - .com 域名下查找DNS解析
                    - .baidu域名下查找DNS解析
                    - www域名下查找DNS解析

如果递归搜索也没有找到的话就会报错了。

不知道你们有没有注意这样一件事,你访问baidu.com的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问,假设只有一个服务器,那它的性能和存储量要多大才能支撑这样大量的访问呢?DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡

更重要的是HTTP缓存

主要分为强制缓存和协商缓存

对于强制缓存,服务器响应的header中这两个字段必须知道——Expires和Cache-ControlExpires是http1.0的产物,只能设置数据失效的时间,现在基本被http1.1中的Cache-Control代替,Cache-Control不仅仅能设置失效的时间(max-age),除此之外还有

public: 客户端和代理服务器都可以缓存。因为一个请求可能要经过不同的代理服务器最后才到达目标服务器,那么结果就是不仅仅浏览器可以缓存数据,中间的任何代理节点都可以进行缓存。

private: 这种情况就是只有浏览器能缓存了,中间的代理服务器不能缓存。

no-cache: 跳过当前的强缓存,发送HTTP请求,即直接进入协商缓存阶段

no-store:非常粗暴,不进行任何形式的缓存。

s-maxage:这和max-age长得比较像,但是区别在于s-maxage是针对代理服务器的缓存时间。

对于协商缓存,强缓存失效之后,浏览器在请求头中携带相应的缓存tag来向服务器发请求,由服务器根据这个tag,来决定是否使用缓存。

TCP三次握手

刚开始客户端处于 closed 的状态,服务端处于 listen 状态。然后

1、第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 SN(c) 。此时客户端处于 SYN_Send 状态。

2、第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s),同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 *SYN_REVD *的状态。

3、第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 establised 状态。

4、服务器收到 ACK 报文之后,也处于 establised 状态,此时,双方以建立起了链接。

三次握手不仅仅确认双方的接受能力、发送能力是否正常。还可以指定自己的初始化序列号,为后面的可靠传送做准备。

除此之外还有三个问题,大家可以思考思考答案是什么?为什么会这样?

  1. ISN 是固定的吗?
  2. 什么是半队列连接?
  3. 三次握手中可以携带数据吗?

详解点击这里

发送请求

发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由请求行请求报头请求正文组成。

请求方法有GET,POST,OPTION,DELETE等等

请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。请求报头中会使用很多字段。比如:Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie

请求正文一般会设置请求数据的格式,请求的数据格式一般为json。这时就需要设置Content-Type: application/json

接收响应

返回的响应体由三部分组成:状态码 ,响应报头响应报文

状态码

1xx	Informational(信息状态码)	  接受请求正在处理
	100 表示成功了
	101 Switching Protocols  
        不安全的  正在进行协议切换 http切换https

2xx	Success(成功状态码)            请求正常处理完毕
3xx	Redirection(重定向状态码)		 需要附加操作已完成请求
4xx	Client Error(客户端错误状态码)	服务器无法处理请求
5xx	Server Error(服务器错误状态码)	服务器处理请求出错

平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500

渲染页面

  • 解析HTML形成DOM树
  • 解析CSS形成CSSOM 树
  • 合并DOM树和CSSOM树形成渲染树
  • 浏览器开始渲染并绘制页面

这会引发重绘和回流问题

TCP四次挥手

刚开始双方都处于 establised 状态,假如是客户端先发起关闭请求,则:

1、第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。

2、第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。

3、第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

4、第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态

5、服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

这里特别需要主要的就是TIME_WAIT这个状态了,这个是面试的高频考点,就是要理解,为什么客户端发送 ACK 之后不直接关闭,而是要等一阵子才关闭。这其中的原因就是,要确保服务器是否已经收到了我们的 ACK 报文,如果没有收到的话,服务器会重新发 FIN 报文给客户端,客户端再次收到 ACK 报文之后,就知道之前的 ACK 报文丢失了,然后再次发送 ACK 报文。

至于 TIME_WAIT 持续的时间至少是一个报文的来回时间。一般会设置一个计时,如果过了这个计时没有再次收到 FIN 报文,则代表对方成功就是 ACK 报文,此时处于 CLOSED 状态。

参考资料

DNS域名解析过程

关于三次握手和四次挥手

# 史上最详细的经典面试题 从输入URL到看到页面发生了什么