浏览器行为与HTTP协议

处理流程:

  1. 输入网址并回车,从局域网跳到互联网
  2. DNS服务解析域名,拿到IP地址
  3. TCP连接,三次握手
  4. 浏览器发送http请求
  5. 服务器处理请求并返回HTML报文
  6. 断开连接,TCP四次挥手
  7. 浏览器解析渲染页面

URL到底是什么?

URL( Uniform Resource Locator )统一资源定位符,用于定位互联网上的资源,俗称网址。

scheme://host.domain:port/path/filename

  • scheme: 因特网服务的类型,常见协议有http、https、ftp、file,其中最常见的类型是http。
  • host: 主机(http的默认主机是www)
  • domain: 域名,如baidu.com
  • port: 端口号(http默认端口是80, https默认端口是443)
  • path: 服务器上的路径(如果省略,则文档必须位于服务器的根目录中)
  • filename: 文档/资源的名称

DNS域名解析

DNS域名解析, Domain Name System,就是通过网站的域名获取相对应的ip地址。

  • 顶级域名,二级域名,三级域名……

    这个很好区分,xxx.com 就是顶级域名,也叫做一级域名,有几个点就是几级。.com是根域名

  • 域名资源记录

    有很多域名,域名要对应id,一个对应就叫做一个记录。域名就叫做域名资源。

  • 域名服务器

    需要解析要找到对应的服务器,域名解析的服务器就叫做域名服务器

  • 域名解析

    将域名转换成ip

dns

在几十年前,计算机性能远不如现在,当数据达到百万级时就需要考虑性能问题了!因此不可能把所有域名都放在一个机器上,而且DNS是个高频率访问的东西。
因此,DNS作者想到了一个办法:分级维护

分级维护

  1. 当你访问网站时,首先要内需域名,DNS服务器收到请求后,优先从本地缓存查找,如果缓存没有就需要向根域名服务器去查询;

  2. 根域名服务器只会维护后缀,把后缀拿出来之后告诉DNS服务器这个后缀的服务器要向哪个服务器再次查询;

  3. DNS 收到服务器地址后,接着去找 TLD 服务器,它负责以及域名,同样他也不干活,只会返回名称服务器的ip;

  4. DNS 收到 TLD 服务器返回的地址之后,再到名称服务器上去查询这个域名的ip;

  5. DNS 收到信息后,会将它丢到本地缓存中,才会返回给客户端;

哪些会被收录在本地缓存呢?

高频访问的域名

浏览器通过向DSN服务器发送域名,DNS服务器解析查询到与域名相对应的ip地址,发送给浏览器。浏览器再将IP地址打在协议上,同时请求参数也会在协议打在,一并发送给对应的服务器。也就是发送HTTP请求。

缓存算法

理论上来说,所有的数据都可以写进缓存。但是有的必要,有的没必要,有的可以是临时缓存。

缓存算法最重要的是数据命中率,要不断提高这个命中率,就需要动态的维护缓存里面的数据。

记录类型解释
SOAStartOf Authority, 起始授权记录。一个区域有且只有一个SOA记录,一般不用管
A记录(主机记录)用于名称解析的重要记录,将特定的主机名映射到对应主机的IP地址上
CNAME记录(别名记录)用于返回另一个域名,即当前查询的域名是另一个域名的跳转,主要用于域名的内部跳转,为服务器配置提供灵活性
NS记录(域名服务器记录)用于返回保存下一级域名信息的服务器地址,该记录只能设置为域名,不能设置为ip地址
MX(邮件记录)用于返回接收电子邮件的服务器地址
iPv6主机记录(AAAA记录)与A记录对应,用于将特定的主机名映射到一个主机的IPv6地址

TCP 三次握手

我们发送请求有效数据,实际上就是url在应用层加上请求头什么的,传到传输层(TCP),在tcp层加上自己的协议,再进行一次打包传到网络层。
……
一直传到服务端,服务端接收到后再返回给客户端,一层层的剥掉,解包。

在客户端发送请求之前会先发起TCP三次握手,用以同步客户端和服务端的序列号和确认号,并交换TCP窗口大小信息。

TCP 协议是面向连接的,要保证链路的稳定;
UDP 协议本身是不稳定,加上一些自己的控制也可以稳定;

TCP

三次握手是建立连接的时候三次通信过程,发起连接的永远是客户端,接受连接的永远是服务端;

  1. 客户端向服务端发送连接请求报文段。该报文段包含 一个 SYN=1, Seq=X 的数据包,发送完后,客户端进入 SYN-SENT 状态。(第一次握手,由客户端发起,告诉服务器我要发送请求了)

  2. 服务端收到连接请求报文段后,监听状态就会变成SYN-RECEIVED 状态。如果同意连接,则会发送应答,返回一个SYN=1, ACK=X+1, Seq=Y 的响应包,发送完后,(第二次握手,由服务端发起,告诉客户端已做好准备)一个是服务端的数据号,另一个是ACK(应答号,对方发过来的顺序号+1

  3. 客户端接收到连接同意的应答后,还要向服务端发送带 ACK=Y+1, Seq=2 的数据包。客户端发送完后,便会进入 ESTABLISHED 状态,服务端接收到应答后也会进入 ESTABLISHED 状态,此时连接建立成功。

思考

为什么需要三次握手呢?

建立完全连接的前提是,客户端和服务端都能收到自己的东西,只有一边能确定叫半连接!!🥴

为了防止已失效的连接请求报文突然由传送到了服务端,因而产生错误。

数据传输
来来回回多次传输,每次都要带上自己维护的数据号和对方的数据号+1放到应答号上。

发送HTTP请求

老生常谈了,这个可以看另外篇笔记。HTTP (一)

服务端处理请求并返回HTTP报文

如上,HTTP (一)

TCP 四次挥手

四次挥手是断开连接的时候的四次通信过程。

tcp-close

TCP是双向的,所以在断开连接时两端都需要发送FIN和ACK

  1. 客户端向服务端发送报文(FIN包),表示已经没有数据传输了。发送完后,进入 FIN_WAIT_1 状态。
  2. 服务端收到连接释放请求后,会告诉应用层要释放TCP连接。会给客户端发送ACK包,并且服务端会静如 CLOSE_WAIT 状态。客户端接收到,会进入FIN_WAIT_2 状态。
    此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是由于TCP是双向的,所以服务端还是可以发送数据给客户端。
  3. 如果此时还有未发完的数据会继续发送,完毕后会给客户端发送连接释放请求,发送FIN包。发送完后,服务端会进入LAST_ACK 状态。
  4. 客户端收到释放请求后,会向服务端发送确认应答(ACK包),此时客户端会进入TIME_WAIT 状态,该状态会持续2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃),若该时间段内服务端没有重发请求的话,客户端会进入CLOSE 状态。当服务端收到了应答后,也会进入CLOSE 状态。

浏览器解析渲染页面

render-dom

浏览器解析渲染页面分为以下五个步骤:

  1. 根据 HTML 解析生成 DOM 树
  2. 根据 CSS 解析生成 CSS 规则树
  3. 结合 DOM 树和 CSS 规则树,生成渲染树
  4. 根据渲染树计算每一个节点的信息
  5. 根据计算好的信息绘制页面

根据 HTML 解析生成 DOM 树

  • 根据HTML的内容,将标签按照结构解析生成DOM树,DOM树解析的过程是一个深度遍历的过程。即先构建当前节点的所有子节点,再构建下一个兄弟节点。
  • 在读取HTML文档,构建DOM树的过程中,若遇到script标签,就会将GUI线程挂起,执行JS引擎线程。因为他俩是互斥的。直到JS引擎线程空闲时,才会继续GUI线程,从中断的地方继续构建。

根据 CSS 解析生成 CSS 规则树

  • 解析CSS规则树时,JS执行将暂停,直至CSS规则树就绪。
  • 浏览器在CSS规则树生成之前不会进行渲染。

结合 DOM 树和 CSS 规则树,生成渲染树

  • DOM树和CSS规则树全部准备好了以后,浏览器才会开始构建渲染树。
  • 精简CSS可以加快CSS规则树的构建,从而加快页面的响应速度。

根据渲染树计算每一个节点的信息(布局)

  • 布局: 通过渲染树中渲染对象的信息,计算每一个渲染对象的位置和尺寸。
  • 回流: 在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

根据计算好的信息绘制页面

  • 绘制阶段,系统会遍历呈现树,并调用呈现器的'paint'方法,将呈现的内容现实在屏幕上。
  • 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。
  • 回流: 某个元素的尺寸发生了变化,则需要重新计算渲染树,重新渲染。

小知识

重绘repaint和回流reflow区别:
回流:当元素的尺寸或者文档位置发生变化时,需要重新计算渲染树,因此叫做回流/页面重排。
重绘:样式发生了变化,不影响DOM的几何属性,这就是重绘。(只重绘部分元素,并不是整个页面进行重绘)

扩展一下🤔️

1.async和defer的作用是什么?有什么区别?

html-download

其中蓝色线代表JavaScript加载;红色线代表JavaScript执行;绿色线代表 HTML 解析。

  1. <script src="script.js"></script>

浏览器会立即加载并执行指定的脚本,也就是不等待后续载入的文档元素,读到就加载并执行。

会阻塞DOM渲染

  1. <script defer src="script.js"></script> 延迟下载

defer 属性表示异步执行引入的Javascript, 即这段Javascript加载时,HTML并不会停止解析,这两个过程是并行。

不会阻塞DOM渲染

  1. <script async src="script.js"></script> 异步下载

async 属性表示异步执行引入的Javascript,会异步加载,等下载完后会立刻执行。无论此刻是HTML解析阶段还是 DOMContentLoad 触发之后。

会阻塞DOM渲染

提示

defer 与 普通script相比:

  1. 载入Javascript 文件时不阻塞HTML的解析,执行阶段被放到HTML标签解析完成之后。
  2. 在加载多个脚本时, async是无序加载,而defer是有序加载。
Last Updated:
Contributors: kk