面试题:从输入URL到页面展示,都发生了什么?你都答全了吗?

509 阅读8分钟

前言

在地址栏输入词汇,回车,到页面展示,这过程中涉及了浏览器各进程之间的协作,网络通信,页面渲染等等流程,本文将针对这个过程进行探究,争取细化整个过程。

输入url之后的完整示意图.png

如上图,这里涉及到了三个进程之间的协作。 各进程的职责简单概括如下:

  • 浏览器主进程: 用户交互、子进程管理和文件存储等功能。
  • 网络进程:面向渲染进程、浏览器主进程等提供下载功能。
  • 渲染进程:把从网络下载的HTML、JavaScript、CSS、图片等资源解析渲染成页面。由于便利考虑,页面是可以加载第三方的资源的,如果有恶意的脚本注入会危害到用户电脑,所以渲染进程是运行在安全沙箱里的(不能直接操作用户操作系统进行增删改)。

结合上图,概括整个流程如下:

  • 浏览器主进程收到用户输入的URL请求,将它转发给网络进程
  • 网络进程发起网络请求
  • 网络进程接收到了响应头数据,进行解析,并将数据转发给浏览器主进程
  • 浏览器主进程接收到网络进程的消息后,发送“提交导航”的信息给到渲染进程
  • 渲染进程接收到“提交导航”的信息后,便开始准备接收HTML数据,接收数据的方式是直接和网络进程建立数据管道。
  • 最后渲染进程会向浏览器主进程“确认提交”,这时在告诉浏览器主进程已经准备好接收和解析页面数据。
  • 浏览器主进程接收到渲染进程“提交文档”的消息之后,便开始移除之前的旧文档,然后更新浏览器进程中的页面状态。

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

一、处理用户输入

地址栏会判断输入的数据是搜索内容,还是请求的URL。

  • 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的URL。
  • 如果输入内容符合URL规则,那么地址栏会带上相应的协议,合成完整的url。 如会把baidu.com合成https://baidu.com/

当用户输入关键字会回车后,页面即将替换成新的页面。在替换之前,浏览器提供了beforeunload事件。可以利用这个事情,在退出之前进行数据的清理操作,或者是取消导航(即还是停留在当前页面)。

我们在vue项目中利用beforeunload事件做拦截,效果如

<script setup lang="ts">
import { onMounted } from 'vue';

onMounted(() => {
   window.onbeforeunload = (e) => {
    const event = e || window.event;
    event.preventDefault();
    event.returnValue = false;
  
    return '';
  }
})

image.png

如果同意了后续流程,浏览器的页面内容将被替换。如果不同意后续流程,浏览器将停止加载新页面。

二、URL请求的过程

浏览器主进程将会通过进程间通信(IPC)把请求发送到网络进程,在网络进程中真正发起网络请求。

首先,网络进程会查找本地资源是否有缓存。如果有缓存资源,那么直接返回资源给浏览器主进程,如果没有在缓存中找到资源,那么直接进入网络请求流程。

一般用户输入的不是ip地址,而是https://baidu.com/格式的域名,所以需要进行DNS解析,以获取请求域名的服务器的IP地址。如果请求的协议是HTTPS,还需要建立TLS(Transport Layer Security)连接。

接下来就是利用IP地址与对应的服务器建立TCP连接。建立连接之后,浏览器会构建请求行、请求头等信息,并将和该域名相关的Cookie等数据附加到请求头中,然后向服务器发送信息。

服务器接收到请求信息后,会根据请求信息生成响应数据(包括响应行、响应头和响应体等信息),并发送给网络进程。等网络进程接收了响应行和响应头后,就开始解析响应头的数据了。

1.响应头的状态码判断

接收到服务器的响应后,网络进程开始解析响应头,如果发现返回的状态码(Status Code)是301或者302,那么说明服务器需要重定向到其他URL。这时网络进程会从相应头的Location字段中读取重定向的地址,然后再进行DNS解析发起新的HTTP或者HTTPS请求。

如果响应头的状态码是200,表示浏览器可以继续处理该请求。

2.响应数据类型处理

在HTTP头部中有一个Content-Type,他告诉浏览器返回的响应体数据是什么类型(比如是要下载的文件,还是html),然后浏览器会根据Content-Type的值来决定如何显示响应体的内容。

我们在mac终端输入

curl -I https://baidu.com

可以看到返回的Content-Typetext/html

image.png

Content-Type是其他的情况,如字节流类型

image.png

根据Content-Type的类型不同,浏览器会使用不同的处理流程。如果是被判断成下载类型,那么请求会被提交给浏览器的下载管理器,同时该URL请求导航流程就此结束。如果是HTML,浏览器就会继承导航流程,接下来就是渲染进程的出场时间了。

3.准备渲染进程

默认情况下,Chrome会为每个页面单独分配一个渲染进程。

特殊情况,浏览器会让多个页面直接运行在同一渲染进程中。

image.png 如上图,这几个页面都是运行在同一个渲染进程中,他们的进程id是13009

在怎样的情况下多个页面会共享一个渲染进程呢?

答案是同一站点的页面有可能会同享同一个渲染进程。

同一站点指相同的根域名和协议。

举个例子,下面这三个都是HTTPS协议,且根域名也都是juejin.cn

https://juejin.cn/
https://www.juejin.cn/hot/articles
https://juejin.cn/hot/articles:8080

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

渲染进程准备好之后,还不能立即进行文档解析,因为数据还忘了进程中,并没有提交给渲染进程,所以下一步就进入到了提交文档的阶段。

4.提交文档

提交文档指的是,将网络进程接收到的文档提交给渲染进程,具体流程如下:

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

其中,当渲染进程确认提交之后,更新的内容如下图所示:

image.png

所以,地址栏输入一个地址后,之前的页面并没有立即被替换,而是要加载一会儿才会更新页面。

接下来就到渲染HTML内容的阶段了。

渲染HTML见文章渲染流程:HTML、CSS和JavaScript, 是如何变成页面的?

总结

总结一下这整个过程中容易忽略的点

  • 浏览器并不会立即更新到新的页面,可以通过beforeunload事件拦截页面导航
  • 在和服务器请求数据的过程中,需要浏览器主进程、网络进程、渲染进程之间互相配合
  • 在符合同一站点的规定情况下,从A页面打开B页面,这两个页面会共享同一个渲染进程。