我们平时去访问某个网站时,通常会有几种方式去访问,直接通过链接跳转到想要访问的网页,还有一种方式就是输入网址进行访问。那么今天我要介绍的就是当你在浏览器输入网址并且敲下回车后,我们是如何能在浏览器上看到网页的。
正文
浏览器首先会判断该URL是否合法,如果不合法会用浏览器搜索引擎进行搜索,合法的话进入下一步。 如果URL是合法的,会先在本地强缓存中查找对应资源,如果找到了对应的缓存资源,并且这个缓存的max-age没有过期,就命中该资源,返回200状态码和资源。否则就进入下一步。
接下来的过程大致分为两个部分:网络通信和页面渲染。
网络通信
1. DNS解析
首先就是DNS解析,它会根据你输入的域名去查询对应的ip地址,
- 浏览器会先到本地域名服务器,递归查找域名对应的ip
- 找不到,就会进行一个迭代查询,根域名服务器查找域名对应的ip
- 再找不到,就到顶级域名服务器查找域名对应的ip
- 还找不到,就到目标域名服务器查找域名对应的ip
- 找到后,浏览器将ip写入DNS缓存,方便下次直接在本地查找的到这个域名对应的ip
2. 发送请求
当客户端(如浏览器)需要访问一个特定的网络资源时,在DNS解析得到目标服务器的IP地址后,接下来的步骤就是向该服务器发送HTTP请求。HTTP请求消息通常包含三个主要部分:请求行、请求头以及请求体(或称请求主体)。下面是对这些部分的一个概述:
1.请求行:
- 包括三个要素:请求的方法(如GET、POST等),请求的统一资源标识符(URI),以及所使用的HTTP协议版本(如HTTP/1.1或HTTP/2)。
- 例如,
GET /index.html HTTP/1.1
表示使用HTTP/1.1协议向服务器发送一个GET请求来获取名为index.html
的文件。
2.请求头:
- 请求头字段提供了关于请求的附加信息,可以分为几类:
- 专门用于HTTP请求的消息头字段,比如
Host
(指定请求的目标主机名),Accept
(表明客户端能够接受的内容类型),Origin
(请求的来源),Referer
(告诉服务器哪个页面链接了当前请求的页面),User-Agent
(描述了请求者的身份),Accept-Encoding
(列出客户端支持的数据压缩格式),Accept-Language
(表示客户端偏好哪种语言)等。 - 通用头部信息,如
Connection
(控制连接的选项),Cache-Control
(缓存指令),Pragma
(兼容性信息),Date
(请求发出的时间)等。 - 描述请求主体的消息头字段,例如
Content-Length
(主体的长度),Content-Type
(主体的数据类型)等。
- 专门用于HTTP请求的消息头字段,比如
3.请求主体:
-
- 这是可选的部分,只有当请求类型要求发送数据给服务器时才会有。请求主体包含了客户端想要传递给服务器的实际数据,例如在表单提交的情况下,这里会包含用户填写的信息。
3. TCP 三次握手
TCP三次握手大致如下
- 客户端向服务端发送建立连接请求, 客户端进入SYN-SENT状态
- 服务端向客户端发送同意连接的应答,服务端进入SYN-RECEIVED状态
- 客户端收到服务端的同意连接的应答后,再向服务端发送一个确认接收到的应答。 客户端进入 ESTABLISHED状态,服务端也进入ESTABLISHED状态
从这三个步骤可以看出,它就是建立连接的一个过程
相信有的小伙伴有这样的疑问,建立连接为什么一定要三次,客户端先发连接请求,服务端答应请求,服务端发送同意请求,客户端同意就可以连接了,两次不就可以建立连接了吗,
关于这个问题,我们使用假设反证
我们先假设只有两次: 当客户端向服务端发送一个建立连接请求A 通讯兵,如何网络环境差,导致这个通讯兵A丢失了, 根据TCP的超时重传机制,当一定时间后:客户端没有收到服务端请求,客户端会自动再次发送一个 建立连接请求B 通讯兵,这个B成功传给了服务端,服务端会给客户端发送同意连接的应答, 此时成功建立连接当数据通信完成后,客户端和服务端都关闭后,如果这个A请求卷土重来传给服务器了, 服务端就会建立连接进入ESTABLISHED状态,但是客户端此时关闭了,服务器就会陷入一个等待请求状态, 消费服务器性能
如果是三次的话,服务端超过时效没有接收到客户端确认接收到的应答,服务器就会关闭
4. IP协议查询MAC地址并将数据发送的数据链路层
在互联网通信的过程中,当需要将数据从一台设备发送到另一台设备时,首先需要确定目标设备的物理地址(即MAC地址),以便在数据链路层上进行通信。IP协议负责的是网络层的工作,它处理的是基于IP地址的逻辑寻址。然而,当数据需要通过物理网络(如以太网)传输时,就需要使用诸如ARP(Address Resolution Protocol,地址解析协议)这样的机制来查询目标设备的MAC地址。通过ARP协议,发送方可以将一个IP地址映射为物理层上的MAC地址,这一过程发生在数据链路层。一旦获得了目标设备的MAC地址,数据就被封装成帧,并通过数据链路层发送到目标设备,从而实现了在同一网络段内的设备间的数据传输。
5. 数据传输
接下来就可以开始正式的 HTTP数据传输了。其实要说的话,建立连接的时候也就可以传输数据了,只是很小而已。
数据传输用到的是 HTTP协议,TCP协议是专门用来建立连接用的。接下来我会介绍一下http协议的版本更迭
HTTP 0.9 --超文本传输协议
- 实验室传输html文本
- 只有请求行 GET /index.html
- ASCII编码html资源
HTTP 1.0
- 0.9 的问题:多种类型的资源文件需要被传输
- 增加了请求头,响应头 -- 实现客户端和服务端的交流 请求头: accept:text/html accept-encoding:gzip,deflate,br accept-Charset:utf-8 accept-language:zh-CN,zh;q=0.9,en;q=0.8,pt;q=0.7
响应头: Content-encoding:br Content-type: text/html; charset = utf - http状态码
HTTP 1.1
- 1.0的问题:HTTP的短连接
- 1.1 建立了长连接,持久连接
- http队头阻塞: 在一个TCP连接中,存在多个http请求,前一个http请求 的响应没有返回,后一个http请求无法发送
- 对虚拟机的支持
- 请求头增加HOST
- Cookie
HTTP 2.0
- 1.1 的问题:带宽利用率低
- TCP的慢启动
- 同时开启的多条TCP连接相互竞争带宽
- http队头阻塞
· 多路复用:
- 打造了一个二进制分帧层,将多个请求利用二进制分帧层处理成一帧一帧的请求, 每一帧打上相应的id编号,服务器接收到所有的帧后,会根据相同的ID合并成一个 完整的请求。服务器响应该请求,将响应头和响应体发送至二进制分帧层,浏览器 接收到响应帧后自行合并成完整响应体
- 多路复用当中可以给重要的请求资源加上标记,服务器会优先响应权重高的资源
- 同时只能最多开启一条TCP 连接
· 头部压缩
HTTPS VS HTTP
- TLS 协议
- 对称加密:将要传输的数据进行加密
- 非对称加密:为了让双方都拥有相同的密钥
(非对称加密)客户端创建秘钥,服务端创建公钥和私钥,服务端将公钥发布出去,客户端使用公钥加秘钥发送给服务端, 服务端通过私钥解开公钥得到秘钥。这样客户端和服务端就拥有相同的密钥 (对称加密)客户端和服务端各自通过秘钥解密相互传递的数据
HTTP 3.0
- 2.0 的问题:
- TCP的对头阻塞:主要因为超时重传,在传输数据包的过程中,一旦出现某一个包丢失, 后续的所有数据包都要等待丢失的数据包重新整理打包发送,后续包才能继续传输
- TCP 建立连接的延时
- QUIC协议 = TCP + UDP
- 实现了 TCP 的流量拥塞控制
- 集成了 TLS 加密
- 多路复用
- 快速握手
当然我们目前所使用的还是2.0版本。
当传输完数据后,就会断开连接,就是四次挥手
5. 四次挥手
四次挥手过程如下
- 客户端向服务端发送断开连接请求
- 服务端接收到断开连接请求后,返回同意断开的响应,并进入到CLOSE_WAIT状态
- 服务端如果存在没有发送完毕的数据,会继续发送,进入到LAST_ACK状态
- 客户端接收到服务端的应答,客户端进入CLOSE_WAIT状态持续2MSL,并向服务端 发送确认应答。在2MSL时间之后自动进入CLOSE状态,服务端在接收到客户端的确认 应答后也进入CLOSE状态
四次挥手后结束了这次通信
页面渲染
数据传输完成后,浏览器开始解析 HTML 并构建 DOM 树,步骤大致如下
- 接收HTML文档:浏览器接收到服务器发送的HTML文档后,开始解析HTML源代码。
- 构建DOM树:浏览器解析HTML文档时会创建一个DOM(Document Object Model,文档对象模型)树。DOM树是一种树形结构,代表了文档的抽象表示形式,其中每个节点都是文档的一部分,如一个段落、一个列表项或一个图像。
- 解析CSS规则:同时,浏览器也会解析页面中的CSS(层叠样式表)规则。CSS决定了页面元素如何显示,包括颜色、字体大小、布局等属性。
- 构建渲染树:在DOM树和CSS规则都解析完成后,浏览器会根据CSS规则构建渲染树。渲染树是由可见的DOM节点组成的,每个节点都有详细的外观属性(如颜色、大小等)。
- 布局计算(Layout):接下来,浏览器会计算每个节点在页面上的具体位置和大小,这一过程称为布局或重排(re-layout)。浏览器需要根据CSS规则确定每个元素的位置,以及它们是如何相互影响的。
- 绘制(Painting):在布局计算完成后,浏览器将根据渲染树中的信息绘制页面内容到屏幕上。绘制是指将视觉效果实际绘制到屏幕上的过程。
- 处理JavaScript:在整个过程中,如果页面中有JavaScript脚本,浏览器会在适当的时机执行这些脚本。JavaScript可以修改DOM树、改变样式、响应用户事件等,从而动态地更新页面内容。
- 重排与重绘:任何改变页面结构或样式的操作都会触发重排(re-layout),而任何改变外观的操作都会触发重绘(repaint)。这些操作可能会导致浏览器重新计算布局或重新绘制页面的一部分或全部。
- 事件处理:页面加载完成后,浏览器会持续监听用户的交互行为,如鼠标点击、键盘输入等。这些事件会触发相关的事件处理器,可能会进一步修改DOM或执行其他脚本逻辑。
- 优化渲染:现代浏览器还采用了各种优化技术来加速渲染过程,比如提前获取资源(预加载)、并行下载、延迟加载(lazy loading)等。
那么到这从输入url到看到页面的大致就是这样了。