过程分为下方几个流程:
-
DNS解析:把域名解析成IP地址
-
TCP 建立连接:TCP三次握手
-
发送HTTP请求
-
服务器处理并响应报文
-
浏览器解析并渲染页面
-
断开连接:TCP 结束连接
相关知识点:
URL
DNS解析、IP地址
TCP建立连接、三次握手
服务器处理、HTTP请求、状态码
浏览器渲染
TCP连接结束
一、什么是URL?
URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。
一般遵守下面的语法规则:
scheme://host.domain:port/path/filename
各部分解释如下:
-
scheme - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。
-
host - 定义域主机(http 的默认主机是 www,也叫服务器名)
-
domain - 定义因特网域名,比如 baodu.com(后缀结尾: .com 用于商业公司 .org 用于组织、协会等 .net 用于网络服务 .edu 用于教育机构 .gov. 用于政府部门 .mil 用于军事领域)
-
port - 定义主机上的端口号(http 的默认端口号是 80)
-
path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)
-
filename - 定义文档/资源的名称
二、域名解析(DNS)
DNS解析过程就是通过网络查找哪台机器有你需要的资源的过程。
浏览器输入一个域名并不是真正意义上的去查找这个,而是去查找对应域名的IP地址。
域名只是一个别名,方便记忆。
向浏览器的缓存中查找;如果没有则进行下一步;
向系统缓存(本地的hosts文件)中查找;如果没有则进行下一步;
向路由器查询DNS缓存;如果没有则进行下一步;
向ISP(运营商)DNS缓存中查找(比如电信)如果没有则进行下一步;
向根域名服务器 => 顶级域名服务器中查找,同时缓存这个 IP 地址,下次就直接访问了。
eg:DNS解析过程
-
访问客户端DNS缓存:「浏览器缓存 -> 系统缓存(host)-> 路由器缓存」,host可以通过ihost去修改。
-
访问 ISP DNS服务器(ISP,互联网服务提供商,有联通电信移动等。如果你是电信网络,则进入电信的 DNS 缓存服务器,以下简称本地),如果本地服务器有,则直接返回;如果没有,让本地 DNS 服务器去咨询查找。
-
本地去咨询 DNS 根服务器,DNS 根服务器发现是 .com 区域 管理的,告诉本地去咨询它。
-
本地去咨询 .com 顶级域名服务器,.com 顶级域名服务器不太清楚,告诉本地去咨询 github.com 主区域 的服务器。
-
本地去咨询 github.com 主域名服务器,github.com 域服务器查找到对应的 IP 地址,返回给本地。
-
本地服务器通知用户,github.com 对应的 IP 地址,同时缓存这个 IP 地址,下次就直接访问了。
三、TCP 三次握手
在客户端发送数据之前会发起 TCP 三次握手用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。
网上也有很多方便易解的过程,这里我直接引用:
- TCP 三次握手的过程如下:
-
客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
-
服务器发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
-
客户端再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)
- 为啥需要三次握手? 谢希仁著《计算机网络》中讲“三次握手”的目的是**“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”**。
四、向服务器发送HTTP请求
建立TCP连接后,开始向Web服务器发送HTTP请求报文。
-
请求方法包含 8 种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
-
URL 即请求地址,由 <协议>://<主机>:<端口>/<路径>?<参数> 组成
-
协议版本即 http 版本号
五 服务器处理请求并返回 HTTP 报文
服务器接受到请求后,对相应的请求作出相应的处理,处理完成后并作出相应的http 响应报文
** 响应行包含:协议版本,状态码,状态码描述 **
状态码规则如下:
-
1xx:指示信息--表示请求已接收,继续处理。
-
2xx:成功--表示请求已被成功接收、理解、接受。
-
3xx:重定向--要完成请求必须进行更进一步的操作。
-
4xx:客户端错误--请求有语法错误或请求无法实现。
-
5xx:服务器端错误--服务器未能实现合法的请求。
六、浏览器解析渲染页面
不做过多解释,搬我觉得网上比较简单易懂的
浏览器拿到响应文本 HTML 后,接下来介绍下浏览器渲染机制
浏览器解析渲染页面分为一下五个步骤:
-
根据 HTML 解析出 DOM 树
-
根据 CSS 解析生成 CSS 规则树
-
结合 DOM 树和 CSS 规则树,生成渲染树
-
根据渲染树计算每一个节点的信息
-
根据计算好的信息绘制页面
-
根据 HTML 解析 DOM 树
-
根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。
-
在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。
-
根据 CSS 解析生成 CSS 规则树
-
解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。
-
浏览器在 CSS 规则树生成之前不会进行渲染。
-
结合 DOM 树和 CSS 规则树,生成渲染树
-
DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。
-
精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度。
-
根据渲染树计算每一个节点的信息(布局)
-
布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
-
回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。
-
根据计算好的信息绘制页面
-
绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。
-
重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。
-
回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。
七、断开连接
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
-
发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
-
被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
-
被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
-
发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)
浏览器在解析过程中,如果遇到请求外部资源时,请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。