详解输入URL到浏览器页面展示过程都发生了什么
一、简单的过程总体概览
①DNS域名解析
②建立TCP连接
③发送HTTP请求
④服务器处理并返回HTTP报文
⑤浏览器解析渲染页面
⑥关闭TCP连接
二、详细过程解析
1、DNS域名解析
在浏览器输入熟悉的网址 比如www.baidu.com,这个叫做网址,并不是百度真实的地址,互联网中每一台机器都有唯一标识的ip地址。网址和ip地址的转换,就是DNS解析。
网址简单容易记住,但是ip地址很复杂,所以需要一个地址簿记录哪个ip对应哪一个网址,这个地址簿就是DNS服务器。
(1) DNS服务树状结构如下
- 根DNS服务器:返回顶级DNS服务器ip地址
- 顶级DNS服务器:返回权威DNS服务器ip地址
- 权威DNS服务器:返回相应主机ip地址
(2)DNS服务器查找过程
- DNS域名查找,在客户端和浏览器,本地DNS之间是递归查询,在本地DNS服务器与根域及其子域之间是迭代查询
需要获取到域名的对应IP,需要访问域名服务器,域名服务器访问流程大致如下:
查找浏览器缓存 ——> 查找操作系统缓存 ——> 查找路由器缓存 ——> 查找本地DNS缓存 ——> 递归查询
递归过程:
查找就可能找到或者找不到两种情况
①本地DNS服务器找到:在客户端浏览器输入url网址后,在递归查找找到ip地址,任何一个步骤找到都会结束查找过程。
②本地DNS服务器找不到:根据本地DNS服务器设置的转发器进行查询,迭代查找。
(3)解析URL
- 完整的url:协议+域名+端口+路径[+参数] [+描点]
- 解析url是因为某些参数包含的特殊字符会产生歧义,url对非安全字符转义,用的是百分号编码
- encodeURL 不会编译= ? & ;/等符号,所以用来编码整个URL;而encodeURLComponent编码会编译以上特殊字符,所以用来编码参数部分
(4)检查浏览器是否有缓存
注意检查缓存发生在发起请求之前进行
一些概念
强缓存:有效期内的缓存资源直接使用,返回200(没有进行真正的请求)
memory cache:内存中读取,读取速度快,一般页面刷新时用到
disk cache:磁盘中读取,读取速度慢,一般关闭后重新打开用到
协商缓存:超过有效期,写带缓存的资源标识向服务器发起请求,检验是否能用
304:可以继续使用,不携带数据
200:需要用新的资源,并缓存
检查顺序
①通过Cache-Control
和Expires
来检查是否存在强缓存,存在则直接取本地磁盘的html,状态码为200 ,从内存or磁盘
②没有强缓存则会向服务器发起请求(先进行下一步的TCP连接),服务器通过Etag
和Last-Modify
来与服务器确认返回的响应是否被更改(协商缓存),若无更改则返回状态码(304 Not Modified),浏览器取本地缓存
③若强缓存和协商缓存都没有命中则返回请求结果
2、建立TCP连接
首先判断是否是https,若协议是https则作加密处理。
HTTPS由两部分组成HTTP+SSL/TLS,在http上加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS加密,传输的数据自然也是加密后的数据。
HTTPS=HTTP+加密+认证+完整性保护
(1)三次握手建立TCP连接
一些概念
ACK:此标志表示应答域有效,有两个取值:0和1。为1的时候表示应答域有效,反之为0。TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
SYN:在连接建立时用来同步序号。SYN置1就表示这是一个连接请求或连接接受报文。当SYN=1而ACK=0时,表明这是一个连接请求报文。同意建立连接,在响应报文中SYN=1和ACK=1。
FIN:用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
三次握手
建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
刚开始客户端处于Closed的状态、服务器端处于Listen的状态
①第一次握手,客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN©。此时客户端处于 SYN_SEND
状态。
首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。
②第二次握手,服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD
的状态。
在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y
③客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED
状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED
状态,此时,双方已建立起了连接。
确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。
- 发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)
三次握手想要达到什么样的目的
- ①客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
- ②服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常
- ③客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
(2)SSL握手过程
①第一阶段 建立安全能力 包括协议版本 会话Id 密码构件 压缩方法和初始随机数
②第二阶段 服务器发送证书 密钥交换数据和证书请求,最后发送请求-相应阶段的结束信号
③第三阶段 如果有证书请求客户端发送此证书 之后客户端发送密钥交换数据 也可以发送证书验证消息
④第四阶段 变更密码构件和结束握手协议
3、发送HTTP请求
它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象。
Web服务器有Tomcat, Nginx和Apach
HTTP报文分为三份:状态码、响应报头、响应报文
(1)状态码
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值
常见状态码:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求
(2)HTTP缓存
HTTP属于客户端缓存,浏览器有一个缓存数据库,用来保存静态文件。
(3)发送请求获取html页面
通常请求行: 请求的方式(get
或post
) + 请求的资源的位置(url) + HTTP/[版本号](HTTP/1.1)
客户端与服务器之前建立链接,收到服务器的返回比如index.html资源
发送http请求过程:组装http报文并将报文发向指定地址的过程服务器处理并返回HTTP报文
4、服务器处理请求并返回http报文
(1)服务器响应html
服务器可能是server或者cdn
cdn:内容分发网络,加快传输速度。主要是存储静态文件,前端html、css、js、图片文件等
nginx:常用的反向代理服务器。服务器上可能会通过nginx等设置静态资源代理,将url对应的html静态资源返回。
请求SEO页面就需要服务端渲染,服务器根据模板和数据渲染html文件并且返回给前端
服务端渲染:模板语法ejs、art-template;基于vue、react等框架的nuxt.js、next.js
(2)浏览器解析html
浏览器下载html数据,将html文档解析成一个个标签;解析到
客户端开始检查收到的index.html文件中可以建立http请求的标签,可以建立http链接的标签 有link script img video audio iframe,需要注意的是访问服务器资源,等待响应会阻塞浏览器页面渲染,可以使用defer和async新的属性,编排资源加载顺序。
5、浏览器解析渲染页面
浏览器渲染页面
①浏览器解析HTML,构建DOM树
②浏览器解析css,构建CSS Rule Tree规则树
③解析完成后,浏览器引擎根据DOM树和CSS规则构造Render Tree(不包括Header、display:none)
④根据Render Tree布局lay out,计算节点
⑤遍历Render Tree绘制paint
6、关闭TCP连接
四次挥手
①Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态
②Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
③Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态
④Client收到FIN后,Client进入TIME_WAIT_2状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
建立链接和分开链接次数不同的原因是:ack确认 fin完成 不会同时发送
发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态
④Client收到FIN后,Client进入TIME_WAIT_2状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
建立链接和分开链接次数不同的原因是:ack确认 fin完成 不会同时发送
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16151.html