总体分为以下几个过程
- DNS解析:将域名解析为ip地址
- 检查浏览器是否有缓存
- TCP连接:TCP的三次握手
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 断开连接:TCP四次挥手
一. DNS域名解析
URL用于定位网上资源俗称网址,输入网址后首先要通过DNS协议进行域名解析,因为浏览器不能直接通过域名找到对应服务器,需要通过ip地址。
上图中,从主机到本地DNS服务器发出的查询是递归查询,其余三个是迭代查询,因为所有回答都是直接返回给本地DNS服务器的。
递归查询
浏览器,操作系统,以及我们的路由器都会去缓存一些url对应的ip地址,这样我们就可以通过缓存加速DNS的解析,不必每次都去根域名服务器查询。主机向本地域名服务器查询一般使用递归查询。
迭代查询
局部的DNS服务器不会自己向其他服务器进行查询,而是将能解析该域名的服务器的ip地址返回给客户端,由客户端不断地发起查询。本地域名服务器向根域名服务器的查询为迭代查询
- DNS缓存 :DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。
- DNS负载均衡(DNS重定向) DNS负载均衡技术的实现原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时, DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问 引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。
- CDN:就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。
- DNS预解析技术:当你浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在你单击当前网页中的连接时就无需进行 DNS 的解析,减少用户等待时间,提高用户体验。
二. 检查浏览器是否有缓存
1.首先会通过cache-control 和 expires 来检查是否命中强缓存,如果命中的话,会直接从本地内存或者磁盘中获取响应结果,不需要发送HTTP请求。
2.当强缓存未命中,会去建立TCP连接发送HTTP请求,服务器通过E-tag和last-modify 判断资源是否有更新(协商缓存)如果没有更新的话,则返回空,取本地缓存,状态码为304 not modified 。
3.如果强缓存和协商缓存都未命中,则返回请求结果。
【注意】
-
expires 存在很大缺陷,它设置的到期时间是根据系统时间来看的,如果系统时间有误会导致请求不到最新的资源。
-
服务器拿到请求头中的 If-Modified-Since的字段后,会和这个服务器中该资源的最后修改时间Last-Modified对比看是否有更新,但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改,因此出现了E-tag。E-tag是根据当前文件生成的唯一标识,文件内容有改动才会发生变化。
-
存储位置:Service Worker 、Memory Cache 、Disk Cache 、Push Cache
1.Service Worker 是运行在浏览器背后的独立线程,可以用来实现缓存的功能。
2.Memory Cache 也就是内存中的缓存,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。
3.Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,比之 Memory Cache 胜在容量和存储时效性上。
4.Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂。
三 .TCP/IP的三次握手
客户端和服务器再进行请求和响应的动作时,需创建一个TCP连接,这是数据包的传输通道
第一次握手:客户端发送SYN=1,随机生成数据包seq=x到服务器,服务器由SYN=1得知客户端要建立连接。(不可携带数据,这样会让服务器更容易受到攻击)
第二次握手:服务器返回SYN=1,随机产生数据包seq=y发送给客户端,同时发送ACK=X+1,告知客户端你发送的包我接收到了。(不可携带数据,这样会让服务器更容易受到攻击)
第三次握手:客户端首先检查ack是否正确,以及SYN是否为1,发送ACK=Y+1告知服务器数据已经接收,同时发送数据包seq=z。(因为TCP的特点是可靠传输,要确认客户端和服务器的接收能力和发送能力,必须要有第三次握手来确认客户端的接收能力。第三次握手时可以携带数据的。)
SYN攻击
当客户端用不存在的ip地址不断地向服务器发送SYN包,服务器需要回应确认包并等待客户端确认,服务器需要不断重发直至超时,这些伪造的SYN请求会长时间占用==半连接队列==(服务器收到SYN包时此时连接还未完全建立,若队列满了会出现丢包的问题,当三次握手完成后会放在全连接队列)
四.发送HTTP请求
TCP三次握手结束后,开始发送HTTP请求报文 HTTP知识梳理
五.服务器处理请求并返回HTTP报文
六.浏览器渲染页面
浏览器渲染页面的过程主要是解析html文档形成Dom树,解析css形成样式规则树,Dom树和样式规则树共同组成渲染树,浏览器最终显示渲染树形成页面。
解析标签构造Dom树(简单说下我理解的大致过程)
- 解析标签算法大致有四种状态分别是,数据状态,标记打开状态,标记中状态,结束标记打开状态。在数据状态遇到 '<' 则转换为标记开始状态,在此之后遇到a-z字符创建起始标记,状态更改为标记中,接收下一个输入字符/时,会创建关闭标记打开状态,并更改为标记名称状态。直到接收 '>' 字符,将当前的新标记发送给树构造器,并改回数据状态。
- 树构造器接收到标签解析器发送来的起始标签会压入栈,当遇到结束标签时,此时查询栈顶元素,如果和传入的结束标签属于同种类型的标签,则将栈顶元素弹出,向DOM树中加入此节点,然后继续向下解析。
重绘和回流
-
重绘
当元素的样式改变但是没有影响它在文档流中的位置时(比如颜色的改变)就会发生重绘。
-
回流(重排)
当元素的样式改变影响到了文档流(比如元素的尺寸大小)浏览器需要重新渲染称为回流(重排)。发生重排一定会发生重绘,反之则不一定。
-
如何减少重排
- 避免使用table布局
- 避免使用CSS表达式
- 避免频繁操作样式
- 对复杂的动画使用绝对定位使其脱离文档流,否则会引起频繁重排
七.TCP四次挥手断开连接
- 假设由客户端先发起断开连接请求(服务器也可以发起),首先客户向服务器发送一个带有FIN=1的报文段,此时客户端进入FIN-WAIT-1状态,等待一个来自服务器带有确认字段的报文。
- 服务器收到该报文段后,向客户端发送确认报文,客户端收到确认报文后进入FIN-WAIT-2状态,等待来自服务器带有FIN=1的报文段。
- 服务器向客户端发送带有FIN=1的报文段,客户端接收到该报文段后进入TIME-WAIT阶段
- 客户端向服务器发送确认报文段,假设ACK丢失,TIME-WAIT阶段可以使客户端重发确认报文。当确认服务端收到后,进入CLOSED状态
为什么TCP挥手需要四次,握手只需要三次
因为握手的时候ACK确认字段和SYN字段可以同时发送,但是断开连接的时候,当服务器收到来自客户端的FIN时候可能还有报文需要发送,不会立即关闭连接,因此只能先回复一个带有ACK字段的报文告诉客户端“你发送的FIN报文我收到了”,当所有报文发送完毕后,服务器才会发送FIN报文,所以需要四次挥手。