输入 URL 到页面加载完成,发生了什么?
1.浏览器接收URL
URL包含的信息:协议、网络地址:端口号、资源路径、查询字符串?、片段标识符#。
2.如果网络地址不是一个 IP 地址,通过DNS协议解析域名返回一个IP地址
DNS协议:DNS数据库是域名和IP地址相互映射的一个分布式数据库,DNS协议用来将域名转换为IP地址。
操作系统会先检查本地hosts文件是否有这个网址映射关系,如果有就调用这个IP地址映射,完成域名解析。否则,查找本地DNS解析器缓存,如果查找到则返回。否则,查找本地DNS服务器,如果查找到则返回。否则,按根域服务器 ->顶级域,.com->第二层域,example.com ->子域,www.example.com的顺序找到IP地址。
3.浏览器与服务器通过三次握手(SYN,SYN/ACK,ACK)建立TCP 连接
即每次建立连接前,客户端和服务端都要先进行三次对话才开始正式传输内容,三次对话的内容大概是这样的:
(1)客户端:我要连接你了,可以吗?
(2)服务端:嗯,我准备好了,连接我吧。
(3)客户端:那我连接你咯。
为什么需要进行三次握手,而不是两次握手?原因是两次握手不可靠。比如,浏览器发送一个连接请求包A,但包A在半路上堵车了,浏览器就认为包A丢失了,所以重新发生一个请求包B给服务器。服务器收到请求,建立连接。两端进行通信,结束后关闭连接。但是这时候,包A到达了服务器,服务器不知道这是一个无效的包,所以进行响应。这时两次握手已经完成,两端就建立起一个无效的连接。但浏览器认为自己没发出请求,所以不会回应,这样就让服务器白白等待回应,浪费了服务器资源。而三次握手的机制下,浏览器知道自己并没有请求连接,会发送拒绝包给服务器,服务器收到回应后也会结束这次无效的连接。
4.浏览器向服务器发送HTTP请求。
一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。
客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:
1\. 请求方法URI协议/版本
2.请求头(Request Header)
3.请求正文:
5.服务器收到请求,从它的文档空间中查找资源并返回HTTP响应。
HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
6.浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上.
1.解析
浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载, 解析成对应的树形数据结构DOM树、CSS规则树,Javascript脚本通过DOM API和CSSOM API来操作DOM树、CSS规则树。
2.渲染
1 计算CSS样式(JS可动态修改dom或css,进一步改变渲染树和分布)
2 构建渲染树(Repaint:屏幕的一部分要重画,比如某个CSS的背景色变了,元素的几何尺寸没有变。Reflow:几何尺寸变了,我们需要重新验证并计算Render Tree。)
3 确认布局(定位坐标和大小,是否换行,各种position, overflow, z-index属性 ……)
4 绘制(调用操作系统Native GUI的API绘制,将每个节点转化为实际像素绘制到视口上)
7.关闭TCP连接或继续保持连接
通过四次挥手关闭连接(FIN ACK, ACK, FIN ACK, ACK)。
即每次断开连接前,客户端和服务端都要先进行四次对话才正式断开连接,四次对话的内容大概是这样的:
(1)主机向服务器发送一个断开连接的请求。(不早了,我该走了)
(2)服务器接到请求后发送确认收到请求的信号。(知道了)
(3)服务器向主机发送断开通知(我也该走了)。
(4)主机接到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开连接。