浏览器知识点整理(六)导航流程

1,778 阅读9分钟

前言

了解了浏览器的 导航流程,就可以来回答 从输入 url 按下回车到页面展示的过程中发生了什么? 这道经典问题的前半部分了,即 从用户发出 URL 请求到页面开始解析的这个过程,也就是 网络请求部分

我们知道,现在的 Chrome 浏览器是 多进程架构,上面的这道经典问题涉及到的进程有浏览器进程、网络进程和渲染进程,先来简单回顾一下这三个进程的主要职责:

  • 浏览器进程:主要负责页面显示、用户交互、子进程管理、文件存储等功能。
  • 网络进程:主要为浏览器进程和渲染进程提供网络请求资源功能。
  • 渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页。

接下来就 来看看浏览器是怎么通过进程之间的协作来完成网络请求的功能吧!

用户输入

流程从用户在地址栏输入查询关键字开始:

  • 用户在地址栏输入关键字浏览器进程 会判断是请求 url 还是搜索内容
    • 如果是搜索内容,则浏览器会使用默认的搜索引擎,合成带有搜索内容的 url
    • 如果是请求的 url,则根据规则判断是否完整,不完整则根据规则合成完整的 url
  • 按下回车,浏览器进入加载状态
    • 在流程继续之前,浏览器还有一个 beforeunload 事件可以执行,该事件可以做一些数据清理操作,还可以中断流程,取消导航;
    • 如果没有 beforeunload 事件或同意继续后续的操作,则流程继续,浏览器进入加载状态;
    • 但页面还是之前的内容,要到 提交文档 阶段才会被替换新的内容。

例如,下图原来的页面是 https://www.npmjs.com/package/egg 的内容,我在搜索框输入 https://www.npmjs.com/package/koa 后按下回车,浏览器便进入了加载状态(左上角的图标开始转圈圈、左下角说正在等待响应),但是页面还是之前 egg 的内容。

image.png

  • 接下来是进入 网络资源请求过程浏览器进程 通过进程间通信(IPC)把 url 请求交给 网络进程

网络资源请求

查找缓存

上面 浏览器进程 已经把 url请求的活交给了 网络进程,那么接下来具体的请求流程是怎么样的呢?

网络进程并不会直接发起网络请求,因为 没有请求的请求,才是最快的请求

  • 按照 浏览器缓存策略,网络进程会去检查该资源 是否允许缓存Cache-Control),是否在本地缓存了该资源(缓存位置依次查找)
  • 如果有缓存资源则网络进程直接返回资源给浏览器进程,网络请求结束
  • 如果没有找到资源或者需要验证资源是否有效,则会 真正进入网络请求流程

缓存是一个大课题,会在后面性能优化的章节再详细整理。

DNS 解析

网络请求的 第一步是要拿到请求的服务器 IP 地址,因为 网络请求过程归根结底是一个计算机向另一个计算机请求资源,需要通过 IP 地址建立连接的

一般情况下,用户看到的用到的是 域名,是一串用 . 分隔的多个单词,像掘金是 juejin.cn、淘宝是 www.taobao.com、百度是 www.baidu.com,这个域名是极其重要的,它是一个网站的入口,可以说是拥有了一个好域名就拥有了一个好梦想。听说 FACEBOOK 一开始的域名是 thefacebook.com,后来融资了才花 20 万美金买回 facebook.com 的域名,要是穿越回到过去,屯一波域名都可以成为亿万富翁,哈哈。

回到正题,一个域名可以对应多个 IP 地址,它可以是源服务器的 IP 地址,也可以是 CDN 分发的 IP 地址,还可以是迁移服务器时的一些临时 IP 地址,我们可以用域名系统做很多有趣的事情。

为了拿到正确的 IP 地址,它有一套自己的解析系统,这个系统就是 DNS 系统,如果想更多的了解 DNS 系统,可以去看我之前写过的 DNS域名系统有哪些门道?

那么接下来继续 网络请求流程

  • 如果用户输入的就是 IP 地址,则直接进入 TCP 连接阶段
  • 如果用户输入的是域名,则需要进行 DNS 解析,得到服务器的 IP 地址再建立 TCP 连接
    • DNS 也是有缓存的,它的缓存查找过程是浏览器缓存->操作系统缓存->Hosts文件->非权威域名服务器 -> 根域名服务器 -> 顶级域名服务器 -> 权威域名服务器

TCP 连接

网络进程拿到 IP 地址之后则进入 TCP 连接阶段

  • 请求进入 TCP 队列,单个域名是有 TCP 连接限制(最多6个)的,超出限制需要排队。
  • 浏览器和服务端通过三次握手建立 TCP 连接
    • 客户端向服务端发送连接请求报文
    • 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答
    • 当客户端收到连接同意的应答后,要向服务端发送一个确认报文
  • 如果请求协议是 HTTPS,TCP 连接后还要建立 TLS 连接(安全地交换对称密钥)

发出 HTTP 请求

建立连接后,网络进程正式发出 HTTP 请求

  • 浏览器端会构建请求行、请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,然后向服务器发送请求信息
    • 请求行简要地描述了客户端想要如何操作服务器端的资源,由请求方法、请求目标、版本号三部分构成
    • 头部字段是 key-value 的形式, keyvalue 之间用 : 分隔,用 CRLF 换行,表示字段结束。

服务器响应返回数据

  • 服务器接收到请求信息后,会根据请求信息 生成响应数据返回(包括响应行、响应头和响应体等信息)
    • 状态行代表服务器响应的状态,同样由三部分构成:版本号、状态码、原因
  • 服务器返回信息给网络进程,网络进程接收后开始解析
    • 解析响应头
      • 如果发现返回状态码是 301302,则说明服务器需要浏览器 重定向 到其他 url,网络进程会从响应头的 Location 字段里面读取重定向的地址,然后再发起新的网络请求;
      • 如果状态码是 200,那么表示浏览器可以继续处理该请求。
    • 解析响应数据类型:通过 Content-Type 头字段区分数据类型。
      • 如果 Content-Type 字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该 url 请求的导航流程就此结束
      • 如果是 HTML 类型,那么浏览器则会继续进行导航流程;

网络请求拿到 HTML 类型的数据后继续导航流程,由于 Chrome 的页面渲染是运行在渲染进程中的,所以接下来就需要准备 渲染进程 了。

准备渲染进程

  • 默认情况下,Chrome 会为每个页面分配一个渲染进程
    • 通常情况下,打开新的页面都会使用单独的渲染进程;
    • 但是如果从 A 页面打开 B 页面,且 A 和 B 都属于同一站点(拥有相同的协议和根域名)的话,那么 B 页面会复用 A 页面的渲染进程;如果是其他情况,浏览器进程则会为 B 创建一个新的渲染进程。
  • 渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档数据还在 网络进程 中,并没有提交给渲染进程,所以下一步就进入了 提交文档 阶段。

提交文档

提交文档,就是指浏览器进程将网络进程接收到的 HTML 数据提交给渲染进程

具体流程是:

  • 首先当 浏览器进程 接收到 网络进程 的响应数据之后,便向 渲染进程 发起“提交文档”的消息;
  • 渲染进程 接收到“提交文档”的消息后,会 和网络进程建立传输数据的“管道”
  • 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程
  • 浏览器进程 在收到“确认提交”的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 url、前进后退的历史状态,并更新 Web 页面。

这也解释了为什么在浏览器的地址栏里面输入了一个地址后,之前的页面没有立马消失,而是要加载一会儿才会更新页面。

进入渲染阶段

提交文档后,渲染进程 便开始页面解析和子资源加载了。

一旦页面生成完成,渲染进程 会发送一个消息给 浏览器进程,浏览器接收到消息后,会停止标签图标上的加载动画。

导航流程总结

以上就是 从用户发出 URL 请求到页面开始解析的过程导航流程 了。

简而言之,就是下面这样的流程:

  • 浏览器进程把用户输入的 url 组装成完整的 url 后交给网络进程
  • 网络进程通过 DNS 解析拿到 IP 地址与服务端建立 TCP 连接,然后发出 HTTP 请求,在收到服务端响应返回的数据后开始解析处理
  • 网络进程收到 HTML 类型的数据后,通过提交文档把数据提交给渲染进程,准备进入页面渲染阶段

渲染阶段 中浏览器具体做了什么将在下一篇文章中整理输出,敬请关注。

浏览器系列专栏目录