从导航栏里面输入了一个URL之后到底发生了什么???


这里面涉及到了浏览器中, 各个进程之间的配合, 如下图:
image.png

所以在正式流程开始之前, 我们还是先来快速回顾一下浏览器进程、渲染进程和网络进程的主要责任。

  • 浏览器进程:用户交互、子进程管理和文件存储等功能。
  • 网络进程:面向渲染进程和浏览器进程等提供网络下载功能。
  • 渲染进程:将从网络下载的HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面。

渲染进程里所有的内容都是通过网络获取的,会存在一些恶意代码利用浏览器漏洞对系统进行攻击,所以运行在渲染进程里面的代码是不被信任的。这也是为什么Chrome会让渲染进程运行在安全沙箱里,就是为了保证系统的安全。

熟悉了这几个进程的功能之后,我们再来看这张图:
image.png

整个流程中包含了许多步骤,大致过程描述如下:

  1. 首先,用户从 浏览器进程输入请求信息;
  2. 然后,网络进程 发起URL请求;
  3. 服务器响应URL请求之后,浏览器进程开始 准备渲染进程;
  4. 渲染进程准备完毕之后,需要先向渲染进程提交页面数据,我们成为提交文档阶段;
  5. 渲染进程接受完文档信息之后,便开始 解析页面和加载子资源,完成页面的渲染。

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

下面我们来分析这些步骤,同时也就解开这个问题了...

从输入URL到页面展示


1. 用户输入
用户在浏览器地址栏中输入关键字时,地址栏会判断输入的关键字是 搜索内容,还是请求的URL

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

当用户输⼊关键字并键⼊回车之后,浏览器便进入下图的状态:
image.png
从图中可以看出,当浏览器刚开始加载一个地址之后,标签页上的图标便进入了加载状态。但是页面并没变,还是之前的内容。这是因为需要等待提交文档阶段,页面内容才会被替换。

2. URL请求过程
我们知道,我们刚才是在浏览器进程中进行的,现在,浏览器进程会通过进程间通信(IPC),把URL请求发送至网络进程,网络进程接收到URL请求后,会在这里发起真正的URL请求流程。

  • 网络进程会查找本地缓存,如果有缓存资源,那么直接返回资源给浏览器进程;如果没有缓存,就会直接进入网络请求流程。

    1. 第一步: DNS解析,获取请求域名的服务器IP地址。如果请求的协议是HTTPS,那么还需要建立TLS连接。
    2. 三次握手,建立TCP连接。
    3. 浏览器端构建请求行、请求头等信息,并把和该域名相关的Cookie等数据附加到请求头中,然后向服务器发送构建的请求信息。
    4. 服务器接收到信息之后,根据请求信息生成响应数据,并发给网络进程。等网络进程接收了响应行和响应头之后,就开始解析响应头的内容了。
    5. 在接收到服务器返回的响应报文后,网络进程对响应报文进行解析,如果发现返回的状态码是301或302,说明服务器需要浏览器重定向到其他URL。然后网络进程从响应头的Location字段里面读取重定向的地址,然后重新发送请求,又重新开始了。
![image.png](/img/bVbK6zv)
当返回了code码是200之后,表示浏览器可以继续处理该请求。
![image.png](/img/bVbK6Gf)
6. 在处理了跳转信息之后,就需要解析URL请求的数据类型,有时候是一个下载类型,有时候是正常的HTML页面,浏览器会通过**Content-Type**这个字段来告诉浏览器返回的响应数据是什么类型。
我们来看下面这张图: 
![image.png](/img/bVbK6Ri)
从图中可以看到Content-Type返回值是text/html,这就是告诉浏览器,服务器返回的是HTML格式。
还有一个我们常见的返回值,Content-Type: application/octet-stream,他是表示显示的数据是**字节流类型**的,通常情况浏览器会按照下载类型来处理该请求。
不同的Content-Type,后续处理流程截然不同。如果浏览器判断是下载类型,那么这个请求会被提交给浏览器的下载管理器,同时URL请求的导航流程结束。但是如果是HTML类型,浏览器就会继续进行导航流程,进入渲染进程。
7. 准备渲染进程,默认情况下Chrome会为每一个页面分配一个渲染进程。但是,也会有多个页面运行在一个渲染进程中的时候。
这种运行在同一个渲染进程中的原因是因为,这几个页面处于同一个站点下。
同一站点就是同一个根域名(geekbang.org)和同一个协议(https://或http://)下的不同子域名和不同的端口。比如下面这三个:

https://time.geekbang.org
https://www.geekbang.org
https://www.geekbang.org:8080
由于他们是是同一个站点,所以Chrome会将他们放在同一个渲染进程当中,如果是不同的站点,就会另外开启一个渲染进程。
当我们的渲染进程准备好了之后,还是无法进入文档解析状态,因为此时的文档数据还在网络进程中,这就需要下一步,提交文档阶段。

  1. 提交文档,这里的文档指的URL响应体的数据。

      * 提交文档的消息是由浏览器进程发出的,渲染进程接收到之后,会和网络进程建立传输数据的"管道"
      * 等待数据传输完成之后,渲染进程会返回"确认提交"的消息给浏览器进程。
      * 浏览器进程在收到"确认提交"的消息之后,会更新浏览器的界面状态,这些状态包括了安全状态、地址栏的URL、前进后退的历史状态,并更新Web页面。
    ![image.png](/img/bVbK67W)

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

9. 渲染阶段,一旦文档被提交,渲染进程便开始页面解析和子资源加载。也就是说,一旦页面生成完成,渲染进程会发送一个消息给浏览器进程,浏览器接收到消息后,会停止标签图标上的加载动画。
![image.png](/img/bVbK69H)
至此,一个完整的页面就生成了,这时候我们就知道了**从URL到页面展示,这中间发生了什么?**

总结:


  • 我们知道了从输入了URL到一个页面的完整展示,这中间的过程经历了那些进程。
  • 这些进程做了些什么,以及是如何配合的。
  • 这个流程再来简单的总结一下:

    1. 浏览器进程: 地址栏判断是请求关键字,还是URL
    2. 网络进程: 查找本地缓存,有缓存直接取缓存返回给浏览器进程,否则继续。
    3. 网络进程: DNS解析,获取IP并缓存到本地。
    4. 网络请求流程: 建立TCP连接。
    5. 浏览器端: 准备请求报文向服务器发送请求。
    6. 服务器端: 返回响应报文,并发给网络进程。网络进程进行解析响应报文内容。第一: 重定向。第二: 处理响应类型。
    7. 准备渲染进程: 判断是否是同一个站点。
    8. 浏览器发出提交消息,渲染进程接收到之后和网络进程建立连接传输数据的"管道"。
    9. 渲染进程返回确认提交消息给浏览器进程
    10. 浏览器进程收到确认提交之后,更新浏览器界面状态。
    11. 一旦页面生成完成,渲染进程会发送⼀个消息给浏览器进程,浏览器接收到消息后,会停止标签图标上的加载动画。

大V是个啥
10 声望1 粉丝

喜欢前端,不断学习的自我驱动型!!!


« 上一篇
HTTP请求流程