从发出http请求到服务器响应过程

从发出http请求到服务器响应过程

浏览器输入url经历图

分析过程:

1.用户输入url,浏览器内部代码将url进行拆分解析

url解析图

举个例子:

https://xxx.xxxxxx.xxx/article/123456.htm

其中“xxx.xxxxxx.xxx” 表示这台服务器,后面的/article/123456.htm

表示我们请求的文件路径。但是这个路径是相对路径,是以web服务器根目录为起始目录的。

所以一个URL 实际上对应Web服务器里的一个文件资源。如果没有输入路径名,例如只输入 “xxx.xxxxxx.xxx” ,表示访问事先设置的默认文件,常见的有 /index.html 、 /default.html 等等。

对URL 进行解析后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来构造 HTTP 请求报文。HTTP消息格式如图:

域名解析过程

浏览器解析URL 并生成 HTTP 数据结构后,在发给服务器之前,还需要查询域名对应的 IP 地址,因为操作系统发送消息时,必须提供通信对象的 IP 地址。

DNS 服务器就是专门保存 域名与 IP 的对应关系,负责解析域名的服务器 。注意:很多教材都说IP地址不方便记忆,所以才有了域名。其实域名不仅仅是方便记忆,他还有更重要的作用,比如用域名就可以实现一台服务器同时搭建多个网站而共用一个IP。

域名是用句点来分隔的,比如www.xxxxxx.com,这里的句点代表了不同层级的划分。在域名中,越靠右的位置表示其层级越高。

可能因为域名是外国人定义的,所以思维和中国人相反。比如表示一个地点,外国喜欢按照从小到大的顺序说(如XX 街道 XX 区 XX 市 XX 省),而中国喜欢按从大到小的顺序(如 XX 省 XX 市 XX 区 XX 街道)。

最右边的是顶级域名,例如上面的“.com” 。再下面是二级域名 xxxxxx.com。所以域名的层级关系是一个树状结构(域名和域名服务器是两个概念):

根DNS 服务器

顶级域DNS 服务器(com)

权威DNS 服务器(xxxxxx.com

所有的DNS 服务器都有根域DNS 服务器的信息。这样一来,任何 DNS 服务器都可以找到根域 DNS 。因此,客户端只要能够找到任意一台 DNS 服务器,就可以通过它找到根域 DNS 服务器,然后再一步步找到位于下层的某台目标 DNS 服务器。

域名解析过程:

首先查找电脑上的DNS缓存,如果有则解析完毕。否则进入第2步;

客户端向本地DNS服务器(可以在网络属性看到,一般是路由器自动设置,也可也手动设置)发送一个DNS请求,询问 xxx.xxxxxx.com的IP地址。本地DNS收到后,如果缓存里有,则直接返回对应的IP地址。否则第3步;

本地DNS向根DNS发送请求,询问 xxx.xxxxxx.com 的IP地址。根DNS收到后,发现是.com结尾的,便返回.com顶级DNS的地址给本地DNS。本地DNS收到后,向.com顶级DNS发起请求,询问xxx.xxxxxx.com的地址。顶级DNS返回负责xxx.xxxxxx域名的权威DNS地址。本地DNS于是向权威DNS请求,权威DNS查询后返回对应的IP地址。

本地DNS收到后,把结果返回给客户端,再缓存起来。

我们再看下解析过程图解:

3.浏览器费了一顿周折终于拿到了服务器IP,接下来就是网络通信(过程如下图),分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层往上走

首先:应用层客户端发送HTTP请求

HTTP请求包括请求报头和请求主体两个部分,其中请求报头包含了至关重要的信息,包括请求的方法(GET / POST)、目标url、遵循的协议(http / https / ftp…),返回的信息是否需要缓存,以及客户端是否发送cookie等。

请求报文

然后:传输层TCP传输报文

位于传输层的TCP协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数据分割成以报文段为单位的数据包进行管理,并为它们编号,方便服务器接收时能准确地还原报文信息。TCP协议通过“三次握手”等方法保证传输的安全可靠。

客户端发送一个带有SYN标志的数据包给服务端,在一定的延迟时间内等待接收的回复。服务端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后客户端再回传一个带ACK标志的数据包,代表握手结束,连接成功。

SYN (Synchronize Sequence Numbers)同步序列编号

ACK (Acknowledgement)确认字符

下图也可以这么理解:

客户端:“你好,在家不,有你信件。”---SYN

服务端:“在的。”-----SYN/ACK

客户端:“好嘞。”-----ACK

接着:网络层IP协议查询MAC地址

IP协议的作用是把TCP分割好的各种数据包传送给接收方。而要保证确实能传到接收方还需要接收方的MAC地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标。

数据到达数据链路层

在找到对方的MAC地址后,就将数据发送到数据链路层传输。这时,客户端发送请求的阶段结束

再次:服务器接收数据

接收端的服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在运输层通过TCP协议将分段的数据包重新组成原来的HTTP请求报文。

服务器响应请求

服务接收到客户端发送的HTTP请求后,查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码。状态码由三位数字组成,

其中比较常见的是200 OK表示请求成功。

301表示永久重定向,即请求的资源已经永久转移到新的位置。在返回301状态码的同时,响应报文也会附带重定向的url,客户端接收到后将http请求的url做相应的改变再重新发送。

404 not found 表示客户端请求的资源找不到。

最后:服务器返回相应文件

服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了需要调度哪些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。

服务器有自己的MVC 结构(如下图)

关闭TCP连接

为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次握手。

4次握手

上图可以这么理解:

客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。”----FIN

服务端:“收到,我看看我这边有木有数据了。”----ACK

服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。”----FIN

客户端:“好嘞。”----ACK

4.页面的渲染阶段

流程:

解析HTML生成DOM树。

解析CSS生成CSSOM规则树。

将DOM树与CSSOM规则树合并在一起生成渲染树。

遍历渲染树开始布局,计算每个节点的位置大小信息。

将渲染树每个节点绘制到屏幕。

webkit渲染引擎流程

过程的重点:

渲染阻塞

当浏览器遇到一个script 标记时,DOM 构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。

所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:

CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。

JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。

当解析html的时候,会把新来的元素插入dom树里面,同时去查找css,然后把对应的样式规则应用到元素上,查找样式表是按照从右到左的顺序去匹配的。

例如:div p {font-size: 16px},会先寻找所有p标签并判断它的父标签是否为div之后才会决定要不要采用这个样式进行渲染)。

所以,我们平时写CSS时,尽量用id和class,千万不要过渡层叠。

渲染树绘制

在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。

reflow与repaint:

根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:replaint和reflow。

replaint:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。

reflow: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。

所以我们应该尽量减少reflow和replaint,我想这也是为什么现在很少有用table布局的原因之一。

display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。

有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。

有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

猜你喜欢

转载自blog.csdn.net/V13807970340/article/details/129753277