阅读 366

从输入URL到页面展示,这中间发生了什么?(导航流程篇)

这是我参与更文挑战的第12天,活动详情查看:更文挑战

前言

在浏览器输入URL到页面展示,这中间发生了什么?

这是一道经典的题目,学习了李兵大佬的浏览器工作原理,整理了一下学习笔记。

导航流程

用户发出URL请求到页面开始解析的过程,就叫导航流程。

浏览器进程接收用户输入的URL请求,再将该URL转发给网络进程

用户输入URL/查询关键词

浏览器会通过导航栏的查询关键词或URL,根据逻辑规则生成完整的URL地址。

现代的浏览器搜索栏都有内置搜索引擎,当用户输入的是搜索关键词(即不符合URL规则),则会根据用户设置的浏览器默认搜索引擎,合成带查询关键词的URL。

# 输入查询关键词-github,会根据浏览器默认搜索引擎,合成带查询关键词的URL。
https://www.baidu.com/s?ie=UTF-8&wd=github
复制代码

如果用户输入的是符合URL规则的内容,则浏览器地址栏会尝试根据URL规则,合成完整的URL

# 输入符合URL规则的内容-github.com
# 由于缺少协议头,则浏览器会尝试为它补全协议头,合成为完整的URL
https://github.com
# 输入符合URL规则的内容-https://www.qq.com/
# 由于它本身便是完整的URL,浏览器不会做任何URL加工
https://www.qq.com/
复制代码

判断beforeunload事件

在当前页面被替换为新的页面之前,会判断页面有没有beforeunload事件,beforeunload事件常用于完成以下的工作:

  • 页面退出之前的一些数据清理
  • 询问用户是否离开当前页面
  • 取消导航,不执行后续导航流程
window.addEventListener('beforeunload', (event) => {
  // 根据规范,要显示确认,事件处理程序需要在事件上调用preventDefault()
  event.preventDefault();
  // 但是Chrome并没有遵守这个规定,Chrome要求设置returnValue
  event.returnValue = '';
});
复制代码

如果页面没有监听到beforeunload事件,或者事件已经同意进行后续的导航流程,则浏览器便进入加载状态(浏览器图标进入加载状态),进行后续导航流程。

urlToPage1.png

发起 URL 请求

在网络进程中发起真正的 URL 请求。

如果浏览器本地缓存了这个资源,则会直接将数据转发给浏览器进程,否则网络进程会接收并解析响应头数据,才会把数据转发给浏览器进程。

URL转发给网络进程

当完成了上述的工作,浏览器进程会通过**IPC(进程间通信)**把URL请求转发给网络进程,网络进程在接收到请求后,会发起真正的URL请求流程。

查找本地资源缓存

网络进程会先查找本地是否缓存了这个资源,如果有缓存,则直接返回资源给浏览器进程。

进入网络请求流程

如果没有查找到缓存资源,则进入网络请求流程。

DNS解析

根据URL查询对应的DNS缓存是否存在,且在有效期内,符合则直接返回缓存存储的服务器IP地址。

如果没有符合的DNS缓存,则会经过DNS服务器解析,得到服务器的IP地址,如果是HTTPS协议,还需要建立TLS连接。

建立TCP连接

利用IP地址和端口号(HTTP默认80端口,HTTPS默认443端口)建立TCP连接(同一域名同时最多只能建立6个TCP连接,超出连接数的请求需排队等待),随后浏览器会构建请求行,请求头(包含Cookie等数据),请求体等信息,向服务器发送请求信息。

服务器接收到信息后,会根据请求信息生成响应行、响应头和响应体等响应信息,并发送给网络进程。

网络进程接收到这些信息后,就开始解析响应信息了。

根据状态码处理请求

如果服务器返回的响应头状态码为301或者302

  • 301: 永久重定向,一般用于重定向被移除的资源
  • 302: 暂时重定向,用于临时重定向

则会根据响应头的Location字段,读取新的被重定向后的URL地址,再发起新的 HTTP 或者 HTTPS 请求,此时一切流程又重新开始了。

如果服务器返回的响应头状态码为200(正常响应),则会根据服务器返回的响应体数据类型(Content-Type),决定如何显示响应体的内容。

# 告诉浏览器返回的是HTML格式的数据
Content-Type: text/html
# 告诉浏览器返回的数据是字节流类型,通常浏览器会安装下载类型来处理
Content-Type: application/octet-stream
复制代码

如果是下载类型的数据,浏览器会把它提交给浏览器的下载管理器,此时,这个导航流程也结束了。

如果是HTML,则浏览器会继续进行导航流程。

准备渲染进程

默认情况下,Chrome会为每个页面分配一个渲染进程(每打开一个新页面就会配套创建一个新的渲染进程)。

但是在同一站点的情况下,多个页面会复用同一个渲染进程,Chrome官方把这个默认策略叫 process-per-site-instance。

同一站点(same-site)

满足以下所有条件,则表示为统一站点

  • 根域名相同
  • 协议相同

同一域名的条件只判断根域名和协议,所以,同一站点的定义还包含了该根域名下的所有子域名和不同端口。

# 这些情况都属于同一个站点
https://www.github.com
https://api.github.com
https://www.github.com:8081
复制代码

提交文档

  • 当浏览器进程接收到网络进程的响应头数据后,便向渲染进程发起"提交文档"的信息。

  • 渲染进程接收到"提交文档"的信息后,会和网络进程建立数据传输的"管道"。

  • 等待文档数据传输完成后,渲染进程会返回"确认提交"的信息给浏览器进程。

  • 浏览器进程接收到"确认提交"的消息后,便开始移除之前旧的文档,然后更新浏览器的界面状态(包括了安全状态、地址栏的 URL、前进后退的历史状态),并更新页面(从此前 URL 网络请求时的逆时针旋转,即将变成顺时针旋转)。

到这里,一个完整的导航流程就完成了,这之后就要进入渲染阶段了。

渲染流程的笔记会放到下一篇文章。

文章分类
前端
文章标签