Site Overlay

输入url到返回请求的过程

输入url按下回车后大概经历了这些过程吧?。。。

  • DNS解析
  • 发起TCP连接
  • 发送HTTP请求
  • 服务器处理请求并返回HTTP报文
  • 浏览器解析渲染页面
  • 连接结束

第一步:浏览器对url解析,DNS域名解析

为什么需要解析?
因为网络标准规定了URL只能是字母和数字,还有一些其它特殊符号。

DNS解析过程
1. 操作系统先查本地hosts文件是否有记录,有就返回映射的IP
2. Hosts文件没有就查本地DNS解析器有没有缓存
3. 计算器配置的DNS服务器有没有缓存
4. 都没有就进行DNS服务器递归查找

递归查找是怎么样的呢?
以查找www.baidu.com这个域名为例
1. 先去根域名服务器查找
2. 没有去.com顶级域名服务器查找
3. 没有去baidu.com二级域名服务器查找
4. 找到了,baidu.com域名服务器返回的IP地址

.就是根域名服务器,其实所有域名最后一位都有.,代表.root,因为大家都有就省略了!

DNS前端优化
一次DNS解析需要耗费20-120毫秒,可以通过预解析减少DNS解析时间和次数

<!-- 告知浏览器,当前页面我要做DNS预解析 -->
<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="xxx" /> <!-- 要做预解析的地址 -->

dns-prefetch需要谨慎使用,多个页面重复使用反而会增加DNS查询次数!

第二步:建立TCP连接

三次握手
第一次握手:主机A发送数据包(位码为SYN=1包,随机产生的序号seq)给服务器,主机B通过SYN=1知道,A要求建立连接
第二次握手:服务器收到SYN包,向A发送数据包(ACK=主机A的seq + 1SYN=1, 随机产生的seq序号)
第三次握手:主机A检查ack是否正确,以及SYN是否为1,主机A会在发送ACK(主机B的seq+1),主机B确认seq值,连接建立成功

为什么是三次而不是两次呢???
? TCP是可靠传输,三次握手是为了确认双发都有接收和发送的能力,否则容易出现丢包现象。第一次握手确认了主机A的发送能力,第二次握手确认了服务端的发送能力和接收能力,第三次握手确认了主机A的接收能力。

四次挥手
第一次挥手:客户端发送FIN=1,序号seq=之前数据最后一个字节的序号+1,进入FIN-WAIT-1状态
第二次挥手:服务器收到FIN包,发送ACK=收到的seq+1和自己的序号seq,服务器进入CLOSE-WAIT状态,这时候客户端处于半关闭状态,虽然不发送数据,但服务器还有数据要发,客户端需要接收,客户端进入FIN-WAIT-2状态
第三次挥手:服务器发送FIN,代表不发数据了给客户端了,进入LAST-ACK状态
第四次挥手:客户端收到Fin后,发送ACK=收到序号+1,进入TIME-WAIT状态,等2MSL后进入CLOSED状态

MSL:最大报文寿命

为什么需要等待一段时间才进入CLOSED状态?

为了重传最后一个ACK报文,如果客户端没有收到ACK的话,服务器会重传FIN报文(问题:为什么是2MSL呢?而不是MSL呢?–> 指一个来回)

第三步:发送HTTP请求

浏览器首次加载资源成功时,服务器返回200,它会把资源下载下来,并把response和header一起缓存,下一次加载资源时会从缓存中拿。
HTTP缓存规则
强缓存:当有未失效缓存资源,通过header中cache-control和expires来判断是否命中强缓存。如果命中,客户端直接从强缓存中将数据拿出来使用。如果没有命中,就直接进入协商缓存的步骤。。。
协商缓存:向服务器发送header带有If-None-Match和If-Modified-Since的请求,比较标识(Etag),验证其是否失效,如果未失效服务端返回304,客户端直接缓存中拿数据,不返回资源内容;如果失效,则请求获取返回的新数据,并更新header中缓存相关的字段~

注:强缓存的优先级比协商缓存更高,如果两种缓存都存在,则直接走强缓存

请求返回的报文中就是我们需要的资源(HTML,CSS,JS)

第四步:浏览器解析渲染页面过程

  1. 解析HTML形成DOM树
  2. 解析CSS形成CSSOM树
  3. 下载并执行js代码
  4. 合并DOM树和CSSOM树形成渲染树
  5. 绘制页面(回流和重绘),浏览器计算DOM节点的位置和宽度等的过程称回流。等确定好这些,浏览器开始绘制内容的过程称为重绘