浏览器打开www.baidu.com的流程

概述

  1. www.baidu.com 这个网址进行DNS域名解析,得到对应的IP地址
  2. 根据这个IP,找到对应的服务器,发起TCP的三次握手
  3. 建立TCP连接后发起HTTP请求
  4. 服务器响应HTTP请求,浏览器得到HTML代码
  5. 浏览器解析HTML代码,并请求HTML代码中的资源(js、css、图片等)
  6. 浏览器对页面进行渲染呈现给用户
  7. 服务器关闭TCP连接

注: 为什么HTTP协议要基于TCP来实现?

TCP是一个端到端的可靠的面向连接的协议,HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,会重传)

浏览器的渲染过程:

解析文件

  • html文件转换为DOM树
  • css文件转换为CSSOM树
  • 将DOM树和CSSOM树合并生成渲染树

绘制图层

  • 根据渲染树生成布局渲染树(回流)
  • 根据布局渲染树生成绘制渲染树(重绘)

合成图层

  • 根据绘制渲染树合成图层显示在屏幕上

各个步骤具体细节

DNS解析(域名解析服务器)

访问过程:

  • 浏览器会首先看自身有没有对这个域名的缓存,如果有就直接返回,如果没有就去问操作系统
  • 操作系统里会对 DNS 解析结果做缓存,如果缓存中有直接返回 IP 地址
  • 如果还没有找到,那么尝试从hosts文件里面去找
  • 在前面三个过程都没有获取到的情况下,就递归地去域名服务器去查找,具体过程如下
    • 客户端发出DNS请求,并发送给本地 DNS 服务器。
    • 本地域名服务器的缓存中没有,就去问根 DNS 服务器(.)
    • 根 DNS 服务器收到本地 DNS 的请求后,发现后置是 .com就给.com 顶级域名服务器地址,接着问顶级域名服务器
    • 顶级域名服务器给出负责 www.server.com 区域的权威 DNS 服务器的地址,接着去问权威 DNS 服务器
    • 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
    • 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。

DNS在哪些场景下会用TCP / UDP? DNS缓存中,原始的域名和IP地址发生改变,那需要过一段时间去更新缓存中的数据,更新的时候又向上发一次请求,请求IP地址,对比缓存中的IP。这次更新的请求就是 TCP 。但是查询的时候使用的是UDP。 原因:数据包数量 2/9,效率和代价的影响,还有DNS数据载荷非常小,是小量的数据传输,使用UDP的时候能够承载的了,但是更新的时候,追求反而是数据传输的可靠性,所以采用TCP。

TCP连接建立(三次握手)

  • 一开始,客户端和服务端都处于CLOSED状态。先是服务端主动监听某个端口,处于LISTEN状态
  • 然后客户端主动发起连接SYN,之后处于SYN-SENT状态
  • 服务端收到发起的连接,返回SYN,之后处于SYN-SENT状态
  • 服务端收到发起的连接,返回SYN,之后处于SYN-RCVD状态
  • 客户端收到服务端发送的SYNACK之后,发送对SYN确认的ACK,之后处于ESTABLISHED状态,因为它一发一收成功了。
  • 服务端收到ACKACK之后,处于 ESTABLISHED 状态,因为它也一发一收了。

所以三次握手目的是保证双方都有发送和接收的能力

发起HTTP请求(建立连接后)

HTTP请求报文由三部分组成:请求行、请求头、空格、请求正文

请求行:用于描述客户端的请求方式(GET/POST等),请求的资源名称(URL)以及使用的HTTP协议的版本号

请求头:用于描述客户端请求哪台主机及其端口,以及客户端的一些环境信息等

空行:空行就是\r\n(POST请求的时候有)

请求正文:当使用POST等方法的时候,通常需要客户端向服务器传递数据。这些数据就存储在请求正文中(GET方法是保存在url地址后面,不会放到这里)

GET请求 POST请求

服务器响应http请求,浏览器得到html代码

HTTP响应也由三部分组成:状态行、响应头、空格、消息体 状态行包括:协议版本、状态码、状态码描述 状态码:状态码用于标识服务器对请求的处理结果

1xx: 指示信息------标识请求已经接受,继续处理

2xx: 成功------表示请求已经被成功接收、理解、接受

3xx: 重定向------要完成请求必须更进一步的操作

4xx: 客户端错误------请求有语法错误或请求无法实现

5xx: 服务器端错误------服务器未能实现合法的请求

常见:200 (OK)、204 (响应头没有 body 数据)、206 (返回的 body 数据并不是资源的全部,而是其中的一部分)、301 (永久重定向,需要改用新的URL)、302 (临时重定向)、304 (重定向已存在的缓冲文件)、403 (服务器禁止访问资源,并不是客户端的请求出错)、404 (请求的资源在服务器上不存在或未找到)、500(服务器这边有问题)

响应头:用于描述服务器的基本信息,以及客户端如何处理数据

空格:CRLF(\r\n)分割

消息体:服务器返回给客户端的数据

解析文件

HTML文档描述一个页面的结构,浏览器通过HTML解析器将HTML解析成DOM树结构。HTML文档中所有内容皆为节点,各节点间拥有层级关系,彼此相连,构成DOM树。构建DOM树的过程:读取HTML文档的字节 ,将字节转化成字符 ,依据字符 确定标签 ,将标签转换成节点 ,以节点为基准构建DOM树

浏览器通过CSS解析器将CSS解析成CSSOM树结构,与DOM树结构较像。CSS文档中所有内容皆为节点,与HTML文档中的节点一一对应,各节点间拥有层级关系,彼此相连,构成CSSOM树。构建CSSOM树的过程:读取CSS文档的字节(Bytes),将字节转换成字符(Chars),依据字符确定标签(Tokens),将标签转换成节点(Nodes),以节点为基准构建CSSOM树。与DOM树的构建过程完全一致。

在构建DOM树的过程中,当HTML解析器遇到<script>时会立即阻塞DOM树的构建,将控制权移交给浏览器的JS引擎,等到JS引擎运行完毕,浏览器才会从中断的地方恢复DOM树的构建。<script>的脚本加载完毕,JS引擎通过DOM APICSSOM API操作DOM树和CSSOM树。为何会产生渲染阻塞呢?其根本原因在于:JS操作DOM后,浏览器无法预测未来DOM的具体内容,为了防止无效操作和节省资源,只能阻塞DOM树的构建。

绘制图层

进入绘制阶段,遍历渲染树,调用渲染器的paint()在屏幕上绘制内容。根据渲染树布局计算布局样式,即每个节点在页面中的布局、尺寸等几何属性。HTML默认是流式布局,CSS和JS会打破这种布局,改变DOM的集合属性和外观属性。在绘制过程中,根据渲染树布局,再根据布局绘制,这就是回流重绘

  • 回流:几何属性需改变的渲染
  • 重绘:更改外观属性而不影响几何属性的渲染

当生成渲染树后,至少会渲染一次。在后续交互过程中,还会不断地重新渲染。这时只会回流重绘或只有重绘。因此引出一个定向法则:回流必定引发重绘,重绘不一定引发回流。

服务器关闭TCP连接

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

为什么挥手需要四次?

再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了。

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACKFIN 一般都会分开发送,因此是需要四次挥手。

相关推荐
程序员清风43 分钟前
Dubbo RPCContext存储一些通用数据,这个用手动清除吗?
java·后端·面试
南北是北北1 小时前
JetPack ViewBinding
面试
南北是北北1 小时前
jetpack ViewModel
面试
渣哥2 小时前
Lazy能否有效解决循环依赖?答案比你想的复杂
javascript·后端·面试
前端架构师-老李3 小时前
面试问题—你接受加班吗?
面试·职场和发展
ANYOLY3 小时前
多线程&并发篇面试题
java·面试
南北是北北4 小时前
RecyclerView 的数据驱动更新
面试
uhakadotcom4 小时前
coze的AsyncTokenAuth和coze的TokenAuth有哪些使用的差异?
后端·面试·github
Chejdj4 小时前
StateFlow、SharedFlow 和LiveData区别
android·面试
道可到4 小时前
直接可以拿来的面经 | 从JDK 8到JDK 21:一次团队升级的实战经验与价值复盘
java·面试·架构