从输入URL到页面展示,这中间发生了那些过程(1)?

从输入URL到页面展示,这中间发生了那些过程?这是一道十分经典的面试题,我们应该首先从宏观的角度,也就是浏览器的多进程架构来分析这个过程中有哪些进程有参与和配合?其次我们应该从微观的角度细致入微的搞清楚每一个步骤发生了什么事情,只有这样才可以完整清晰的回答好这个面试题。

浏览器多进程间的协作过程

在这整个过程中,浏览器的主进程、渲染进程和网络进程参与了工作,它们是互相配合来完成这一从输入URL到页面展示的流程的,三个进程的主要分工如下:

  • 浏览器进程:主要负责管理各个子进程、页面交互和文件存储功能
  • 渲染进程:主要负责将网络进程中加载好的HTML、CSS、Javascript和图片等资源进行解析渲染,对于Chrome来说其渲染引擎blink和JS解析引擎V8都是在这个进程中工作的
  • 网络进程:主要负责发起HTTP请求,将服务器返回的资源进行下载

了解了以上三个进程的主要功能之后,就可以从浏览器进程的角度来分析以下输入URL到页面展示经历了那些过程:

  1. 浏览器进程接收到用户输入的URL地址,浏览器进程会将其URL地址转发给网络进程
  2. 网络进程发起真正的HTTP请求
  3. 随后,网络进程接收到服务器返回的响应头数据,开始解析响应头数据,并将数据转发给浏览器主进程
  4. 浏览器主进程接收到响应头数据,发送一个名为"提交导航CommitNavigation"d的消息给渲染进程
  5. 渲染进程接收到"CommitNavigation"的消息之后,便和网络进程建立一个管道,开始准备接收HTML数据
  6. 准备好之后,渲染进程向主进程发送一个"确认提交"的信息,此时便等于告诉浏览器可以开始接收和解析数据了
  7. 浏览器进程中接收到渲染进程"提交文档"的消息之后,便开始移除旧的文档,更新页面

从输入URL到页面展示的详细流程

1. 用户输入

浏览器首先会判断用户在地址栏中输入的是查询关键字还是合法的URL地址?
如果是查询关键字,那么浏览器会基于当前设置的默认的搜索引擎来合成带搜索关键字的URL
如果是合法的URL地址,那么浏览器会将URL地址提交给网络进程

注意:在正式发起请求之前,还需要判定当前页面是否绑定了onbeforeunload事件

  • beforeunload事件何时触发
    beforeunload事件在当页面卸载(关闭)或刷新时调用,事件触发的时候弹出一个有确定和取消的对话框,确定则离开页面,取消则继续待在本页。

  • 绑定beforeunload事件的场景
    清理一些多余的数据,清除定时器
    在表单收集的页面,可以询问用户是否确定退出,避免当前页面有未提交的表单
    拦截浏览器的导航,让浏览器不在执行后续的跳转

如果页面没有监听beforeunload事件或者同意继续之后,浏览器标签页左上角的favicon便开始展示为loading状态,此时浏览器进程会基于进程间通信IPC的方式将URL地址转发给网络进程,用于发起正式的HTTP请求。

2. URL请求流程

查找缓存

首先查询浏览器本地是否缓存了需要请求的资源(关于浏览器的缓存策略后续会专门写一篇文章来进行说明),如果本次缓存中有那么直接将资源返回给浏览器进程;如果没有查询到那么直接进入真正网络请求的流程。

DNS解析获取IP地址

基于URL地址确认请求的服务器的IP地址和端口号,IP地址是基于DNS域名解析服务进行查询,当前DNS也会在浏览器本地有缓存,如果有缓存直接获取即可。端口号的话一般HTTP协议是80;HTTPS协议是443端口。至于为什么要获取IP地址和端口号,这是因为HTTP协议是应用层的协议,传输数据是基于底层的tcp协议和ip协议来进行传输的,具体的做法是在传输的数据包前面加上一个tcp头信息和ip头。

注意如果这里是https请求的话,还需要在建立TCP连接之间建立TLS连接。

建立TCP连接

基于IP地址和服务器建立TCP连接,这里就设计到客户端和服务器的三次握手操作,也就是双方会总共发送3个数据包来确认建立连接。

浏览器发送请求

浏览器端开始构建请求行、请求头和请求体等信息,将浏览器的一些基础信息和cookie等信息添加到请求头中,然后向服务器发送构建好的请求报文。

服务器响应数据

服务端接受到请求报文之后,会根据报文信息生成响应头、响应行和响应体等数据,等网络进程接受到响应头和响应行之后,就可以解析响应头中的内容。等网络进程解析完成响应头信息之后,将会将其转发给浏览器进程处理

影响后续流程的两个信息

  1. 响应行中的301/302状态码 执行重定向
    解析响应头时还需要注意一个重定向的操作:如果返回的是响应行信息为301/302,代表需要进行重定向至其他URL地址,此时网络进程会从响应头中读取到location字段的值,并重新发起http/https请求。

  2. 响应头中的Content-Type
    网络进程会首先基于响应头中的Content-Type字段来确定服务器返回的何种类型的资源文件,因为不同的资源类型浏览器对其处理不一样:

  • 如果这里接收到的是一个text/html类型的文件的话,那么意味这是一个HTML类型的文件,此时网络进程将响应头数据转发给浏览器进程,浏览器进程就通知渲染进程要准备渲染了。

  • 而如果是一个application/octet-stream也就是二进制字节流类型的文件,那么浏览器会将其提交给下载管理器进行下载。

3. 准备渲染进程

一般情况下,浏览器主进程会为每一个标签页都准备一个渲染进程,但是这里有一个特殊情况,那就是如果当前页面和新的页面属于同一站点,那么新的页面不会再有新的渲染进程,而是复用原来的渲染进程。

什么是同一站点?
同一站点的意思就是站点与站点之间的协议和根域名相同,那么根域名下的所有子域名以及所有端口号组成的站点都属于同一站点。

渲染进程准备好之后,还不能立即进入解析文档的流程,因为此时资源还在网络进程,还没有提交给渲染进程,那么下一步就是提交文档阶段。

4. 提交文档

当浏览器进程接收到网络进程的响应头数据之后,便向渲染进程发送一个“提交文档”的信息
渲染进程接受到该信息之后,便基于IPC建立和网络进程的数据传输管道
随后便是等待文档传输完成之后,渲染进程会返回一个"确认提交"的信息给浏览器主进程
浏览器主进程在收到该消息之后,此时会更新新页面的安全状态、前进后退状态。

5. 渲染页面

一旦文档确认提交之后,渲染进程就开始解析资源和渲染页面了,注意浏览器的渲染页面不是等待所有资源都加载完成之后才开始渲染,而是一边解析一遍渲染的,这也是为什么有的页面会先给用户呈现文字,然后图片等资源才会随后加载。

posted @ 2021-12-02 23:15  小高同学1997  阅读(137)  评论(0编辑  收藏  举报