简单版
1.浏览器地址栏输入URL地址,回车
2.浏览器查找当前URL是否存在缓存,并比较缓存是否过期
3.DNS解析URL对应的IP
4.根据IP建立TCP连接(三次握手)
5.发送HTTP请求
6.服务器处理请求,浏览器接受HTTP响应
7.浏览器解析并渲染页面
8.关闭TCP连接(四次挥手)
高级版
-
浏览器输入URL 输入URL,按下回车,就进入
应用层往下走,浏览器会开一个线程处理,对URL解析。 -
应用层DNS解析域名
DNS解析就是对域名或IP解析- 首先查看浏览器DNS缓存
- 没有就查询计算机本地DNS缓存
- 还没有就询问递归式DNS服务器
-
应用层客户端发送HTTP请求 IP地址有了,
客户端就会发送一个HTTP请求,HTTP请求分为请求报头和请求主体- 请求报头包含:请求方法(POST,GET等),协议版本号,请求头部方法(Accept、Cache-Control...)
- 请求主体:客户端发送给服务器或者服务器返回给客户端的内容
-
传输层TCP传输报文 客户端在传输层开始和服务器通过
三次握手建立TCP/IP连接 -
网络层IP协议查询MAC地址 网络层IP协议会查询MAC地址进行数据包的传输
-
数据到达数据链路层 找到对方的MAC地址后,会将数据发送到数据链路层传输,到此客户端发送请求阶段就结束了
-
服务器接收数据 服务器在数据链路层接收到数据包,在通过相反的方式将数据一层一层的还原回应用层 请求到后台服务器,会有验证(安全验证、跨域验证等),验证未通过就直接返回相应的HTTP报文,验证通过,就执行对应的操作 如果浏览器访问过,且缓存上有对应的资源,就会与服务器最后修改的时间对比,一致就返回304,告诉浏览器可使用本地缓存
-
服务器响应请求 服务器接收到客户端发送的HTTP请求后,会查找客户端请求的资源,并返回响应报文。
-
服务器返回相应文件 请求成功后,服务器会返回相应的网页,浏览器接收到响应成功的报文后便开始下载网页,网络通信结束
-
解析HTML构建DOM Tree
-
解析CSS构建CSSOM Tree
-
构建渲染树(Render Tree) 将DOM树和CSSOM树合并成渲染树,渲染树只包含渲染网页所需的节点,然后用于计算每个可见元素的布局,并输出给绘制流程,将像素渲染在屏幕上。
-
布局
-
绘制
-
合成
简洁回答
-
首先,客户端浏览器输入URL,由于是域名,应用层DNS开始解析域名
-
接着,应用层客户端发送一个HTTP请求,把拿到的应用层HTTP请求报文数据分割编号,为了方便安全的传输,传输层会通过TCP三次握手建立TCP/IP链接
-
建立连接后
网络层IP协议会查询服务器MAC地址也就是物理地址进行数据包的传输 -
找到对方的
MAC地址后,将数据发送到数据链路层传输,到此客户端发送请求阶段结束 -
接收端的服务器在
数据链路层接收到数据包,再通过相反的方式将数据一层一层的还原回应用层 -
服务器接收到客户端发送的HTTP请求后,会查找客户端请求的资源,并返回响应报文
-
请求成功后,服务器会返回相应的网页,浏览器接收到响应成功的报文后便开始下载网页,至此,网络通信结束
-
浏览器拿到网页文件后,首先根据顶部定义的DTD类型进行对应解析方式,网页解析会交给内部GUI渲染线程处理
-
接着构建DOM树和CSSOM树,过程中,如果遇到节点是 JS ,就会调用
JS引擎对 JS代码进行解释执行,此时由于JS引擎和GUI渲染线程互斥,GUI渲染线程会被挂起,渲染过程停止,如果 JS 代码的运行中对DOM树进行了修改,那么DOM构建要从新开始,然后DOM树和CSSOM树构建为渲染树 -
然后进入布局阶段,计算渲染树节点在设备视口内的确切位置和大小
-
再接着将渲染树中每个节点转换成屏幕上的实际像素,也就是绘制阶段
-
最后的合成阶段浏览器会将各层信息发送给GPU,GPU将各层合成,显示在屏幕上
详细解析
针对第二项解析
1.HTTP缓存:强缓存 2.HTTP缓存:协商缓存
针对三次握手
- 1.第一次握手:
客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;(由浏览器发起,告诉服务器我要发送请求了)
- 2. 第二次握手:
服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;(由服务器发起,告诉浏览器我准备接受了,你赶快发送)
- 3. 第三次握手:
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。(由浏览器发送,告诉服务器,我马上发,准备接受)
为啥需要三次握手??
三次握手”的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
三次握手过程中可以携带数据么?
第一次、第二次握手不可以携带数据,因为一握、二握还没有建立连接,会让服务器容易受到攻击。 三次握手,客户端处于ESTABLISHED(已建立连接状态),可以携带数据
发送HTTP请求
发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由请求行,请求报头,请求正文组成
服务器处理请求并返回HTTP报文
状态码、响应报头、响应报文
浏览器解析渲染页面
1.解析HTML形成DOM树 2.解析CSS形成CSSOM树 3.合并DOM树和CSSOM树形成渲染树 4.浏览器开始渲染并绘制页面(回流和重绘)
针对四次挥手
1.第一次挥手:
客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1(终止等待1)状态。
2.第二次挥手:
服务端收到FIN包后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE-WAIT状态。客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文。
3.第三次挥手:
服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端就进入了LAST_ACK(最后确认)状态,等待客户端的确认。
4.第四次挥手:
客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手。
简单理解记忆:(FIN:finish,ACK:acknowledge)
- 客户端------FIN------》服务端
- 服务端------ACK------》客户端
- 服务端------FIN------》客户端
- 客户端------ACK------》服务端
总结
由这个问题可以牵扯很多知识点
1:浏览器缓存 2:HTTP 3:回流和重绘 4:JS事件循环 5:垃圾处理机制 6:性能优化
总结:
- URL检测:判断是否是合法URL,域名补全,转义字符编码
- 浏览器本地缓存这个资源,直接讲数据转发给浏览器进程,没有缓存,下一步,DNS解析域名
- DNS解析域名
- TCP三次握手
- 准备请求(请求头,请求体)
- 发送请求,get请求
- 服务器处理请求,查询数据库
- 服务器响应
- 浏览器收到响应头(set-cookie,content-type,缓存,状态码,connection,keep-alive)
- 收响应体
- 渲染
- 解析(预处理线程,资源加载,async defer, prefetch. repload)
- 生成DOM树+CSSOM树
- 样式计算
- Layout布局
- layer分层
- paint绘制
- 主线程结束,
- 根据情况决定是是否断开连接:四次挥手