浏览器工作原理与实践(四)之从URL到页面展示,这中间发生了什么?

 从图中可以看出,整个过程需要各个进程之间的配合,所以在开始正式流程之前,快速回顾一下浏览器进程、渲染进程、和网络进程的主要职责

  • 浏览器进程主要负责用户交互,子进程管理和文件存储等功能。
  • 网络进程是面向渲染进程和浏览器进程提供网络下载功能
  • 渲染进程的主要职责是把网络下载的HTML、Javascript、Css、图片等资源解析为可以显示和交互的页面。因为渲染进程所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所有运行在渲染进程的代码是不被信任的,这也是为什么Chrome会让渲染进程运行在安全沙箱里,就是为了保证系统的安全

回顾了浏览器进程架构之后,再结合上图来看下完整的流程,大致描述如下:

  1. 首先,浏览器进程接受到用户输入的URL请求,浏览器便将该URL转发给网络进程
  2. 然后在网络进程发起真正的URL请求
  3. 接着网络进程接收到了响应头数据,便解析响应头数据,将数据转发给浏览器进程
  4. 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航”消息到渲染进程
  5. 渲染进程收到“提交导航”的消息之后,便开始接收HTML数据,接收数据的方式是直接和网络进程建立数据管道
  6. 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器:“已经准备好接收和解析页面数据了”
  7. 浏览器进程收到渲染进程“提交文档”的消息后,便开始移除旧的文档,更新浏览器进程中的页面状态

 这其中,用户发出URL请求到页面开始解析的这个过程叫做导航

从输入URL到页面展示

1.用户输入

当用户在地址栏输入一个查询关键字时,地址栏会使用输入的关键字时搜索内容,还是请求的URL 

  • 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的URL
  • 如果判断输入内容符合URL规则(baidu.com),地址栏会根据规则,把这段内容加上协议,合称为完整的URL(https://www.baidu.com/)

当用户输入关键字并回车之后,意味着当前页面将被替换为新的页面,不过在这个流程之前,浏览器还给了当前页面一次执行beforeunload事件的机会,允许用户在页面退出之前执行一些数据清理操作,比如常见的“是否离开当前页面”,用户可以通过 beforeunload事件取消导航,让浏览器不再执行后续操作

 当前页面如果没有被beforeunload事件阻止或者没有监听,那么浏览器金额与下图的状态

 

 从图中可以看出,标签页上的图标便进入了加载状态,但此时页面显示还是当前页面,因为需要等待提交文档阶段。

2.URL请求过程

 接下来,便进入页面资源请求过程,这时,浏览器进程会通过进程间通信(IPC)把URL请求发送至网络进程,网络进程接收到URL请求后,会在这里发起真正的URL请求过程,具体过程如下描述:

  • 首先,网络进程会查找本地资源是否缓存了该资源,如果有直接返回资源给浏览器进程,没有则直接进入网络请求流程。第一步进行DNS解析,以获取请求域名的服务器IP地址,如果请求协议是HTTPS,还需建立TLS连接。
  • 然后利用IP地址和服务器建立TCP连接,连接建立后,浏览器构建请求行、请求头等信息,并把和该域名相关的Cookie等数据附加到请求头中,再向服务器发送构建的请求
  • 服务器接收到请求信息,根据请求信息生成响应数据(包括响应行、响应头和响应体等信息),并发给网络进程,等网络进程接收了响应头之后开始解析响应头的内容

重定向:在接受到服务器返回的响应头后,网络进程开始解析响应头,如果发现返回的状态码 301 或者 301,说明服务器需要浏览器重定向到其他URL,然后再次发起新的HTTP或者HTTPS请求,从头开始。

比如

curl -I http://time.geekbang.org/

 curl -I + URL的命令是接收服务器返回的响应头的信息,执行命令后看到响应信息

可以看出,服务器会通过重定向的方式把HTTP请求转换为HTTPS请求,并把响应的Location字段中填上重定向的地址,这就是告诉了浏览器要重新导航到新的地址上。

 下面我们再使用HTTPS发起请求,看看是什么样子 

curl -i https://time.geekbang.org/ 

 返回如下信息:

 可以看出,服务器返回的是200,告诉浏览器一切正常

以上是重定向的内容,在导航过程中,如果服务器的状态码包含了301、302一类的跳转信息,浏览器会跳到响应行的Location字段的地址继续导航,如果是200,表示浏览器可以继续处理盖青青

 响应数据类型处理:URL请求的数据类型有时候是一个下载类型,有时候是正常的HTML页面,那么浏览器如何区分呢?

 答案是 Content-Type。

Content-Type是HTTP头中的一个非常重要的字段,它告诉浏览器服务器返回的响应数据是什么类型。然后浏览器根据这个字段的值来决定如何显示响应体的内容

在终端输入以下命令

curl -i https://time.geekbang.org/ 

从返回的响应体信息来看,其Content-Type的值是text/html,浏览器会认为是展示的页面。

  • 如果Content-Type配置不正确,将text/html配置成 application/octet-stream类型,浏览器可能会去曲解文件内容,将一个展示页面变成了一个下载文件。
  • 如果Content-Type字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该URL请求的导航流程就此结束
  • 如果Content-Type字段的值是text/html,浏览器会继续进行导航流程。

由于Chrome的页面渲染在渲染进程,接下来需要准备渲染进程了

3.准备渲染进程 

默认,Chrome会为每一个页面分配一个渲染进程。但是有一些例外,在某些情况,浏览器会让多个页面运行在同一个渲染进程中,

如图:框出来的页面都是在同一个渲染进程中,进程ID是57434

什么情况下多个页面会同时运行在一个渲染进程呢?

要解决这个问题,我们首先要明白什么是同一站点,

我们将同一站点 定义为根域名(例如cnblogs.com/)加上协议(例如:https://或者http://),还包含该根域名下的所有子域名和不同的端口

 比如

https://i-beta.cnblogs.com/posts/edit
https://www.cnblogs.com/cuixiaohua/p/12694643.html

 它们都是同一站点,因为协议都是HTTPS,根域名都是cnblogs.com

Chrome 的默认策略是,每个标签对应一个渲染进程。但如果从一个页面打开了另一个新页面,而新页面和当前页面属于同一站点的话,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫 process-per-site-instance。

若新页面和当前页面不属于同一个站点,则 

 

从上图看出:博客那几个标签页拥有相同的协议和根域名,所以它们属于同一站点,并运行在同一个渲染进程中,而极客时间会使用一个新的渲染进程

总结来说:

  • 通常情况,打开新的页面都会使用单独的渲染进程
  • 如果从A页面打开B页面,且A和B都属于同一站点,那么B页面复用A页面的渲染进程,如果是其他情况,浏览器进程会为B创建一个新的渲染进程

 渲染进程准备好之后还不能立即进入文档分析状态,因为此时的文档数据还在网络进程中,并没有提交给渲染进程,下一步就到了提交文档阶段

 4.提交文档

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

  1. 首先当浏览器进程收到网络进程的响应头数据之后,便向渲染进程发起“提交文档”的消息
  2. 渲染进程收到“提交文档”消息后,会和网络进程建立传输数据的“管道”
  3. 等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程
  4. 浏览器进程收到“确认提交”消息后,更新浏览器界面状态、地址栏的URL、前进后退的历史状态,并更新web界面

 当浏览器进程“确认提交”后,更新内容如下图:

 这也就解释了浏览器输入一个地址后,之前的页面没有立马消失。

5.渲染阶段

 一旦文档被提交,渲染进程便开始页面解析和子资源加载,这个过程会在下一篇介绍。

这里只先需要了解一旦页面生成,渲染进程会发送一个消息给浏览器进程,浏览器接收到消息后,会停止标签页的加载动画。

在 PDFlux 中打开
无数据
原文地址:https://www.cnblogs.com/cuixiaohua/p/12764900.html