“在浏览器里,从输入 URL 到页面展示,这中间发生了什么? ”这是一道经典的面试题。涉及到一系列的知识考察:网络、操作系统、Web 等。
- 浏览器进程接收到用户输入的 URL 请求,浏览器进程便将该 URL 转发给网络进程。
- 在网络进程中发起真正的 URL 请求。
- 网络进程接收到了响应头数据,便解析响应头数据,并将数据转发给浏览器进程。
- 浏览器进程接收到网络进程的响应头数据之后,发送“提交导航 (CommitNavigation)”消息到渲染进程
- 渲染进程接收到“提交导航”的消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道。
- 最后渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程:“已经准备好接受和解析页面数据了”。
-
浏览器进程接收到渲染进程“提交文档”的消息之后,便开始移除之前旧的文档,然后更新浏览器进程中的页面状态。
用户发出 URL 请求到页面开始解析的这个过程,就叫做导航。
从输入URL到页面展示
一. 用户输入
用户在地址栏输入查询关键字后,地址栏会判断输入的是搜索内容还是请求的URL
-
搜索内容:地址栏会使用浏览器默认的搜索引擎来合成新的带搜索关键字的URL。如在谷歌浏览器地址栏输入
大山
,回车,会看到地址栏的URL变为
https://www.google.com/search?q=大山&oq=大山
-
输入内容符合URL规则:地址栏会根据规则,在前面加上协议合成完整的URL,如:在谷歌浏览器地址栏输入
baidu.com
,回车,会看到地址栏的URL变为https://www.baidu.com/
浏览器开始加载一个地址后,标签页上的图标会变成
loading
,但页面还是显示之前的页面内容,因为需要等待提交文档阶段,页面内容才会被替换。
二. URL请求过程
网络进程会查找本地缓存是否缓存了该资源
- 有缓存资源:直接返回资源给浏览器进程
- 没有缓存资源:直接进入网络请求流程
网络请求流程步骤:
- 进行DNS解析,获取到请求域名服务器的IP地址
- 利用IP地址和服务器建立TCP连接
- TCP连接建立之后,构建请求行、请求头等信息,并把和该域名相关的Cookie等数据附加到请求头中
- 向服务器发送构建的请求信息
- 服务器根据请求信息生成响应数据,包括响应行、响应头和响应体等信息,并把响应数据发给网络进程
- 网络进程解析响应头
6.1. 如果响应头中的状态码是301/302
,网络进程会读取响应行中的Location字段并发起新的URL请求
6.2. 如果响应头中的状态码是200
,网络进程告诉浏览器一切正常,可以继续往下处理该请求了。
如果响应头中的状态码是200
,会继续解析Content-Type
字段
6.2.1. 如果返回的值标识是一个下载文件,则该请求会被提交给浏览器的下载管理器,URL请求的导航流程就此结束。
6.2.2. 如果返回的值标识是一个HTML文件,浏览器会继续进行导航流程,即网络进程会把响应头数据转发给浏览器进程。
三. 准备渲染进程
- 默认情况下,Chrome会为每个页面分配一个渲染进程。
- 如果从A页面打开了B页面,而B页面和A页面属于同一站点的话,那么B页面会复用A页面的渲染进程。官方把这个默认策略叫 process-per-site-instance。
渲染进程准备好之后,还不能立即进入文档解析状态,因为此时的文档数据还在网络进程中,并没有提交给渲染进程,所以下一步就进入了提交文档阶段。
四. 提交文档
所谓的提交文档,是指浏览器进程将网络进程接收到的HTML数据提交给渲染进程。
- 浏览器进程接收到网络进程的响应头数据后,便向渲染进程发起“提交文档”的消息
- 渲染进程接收到“提交文档”的消息后,会和网络进程建立传输数据的“管道”
- 文档传输完成后,渲染进程返回“确认提交”消息给浏览器进程
- 浏览器进程接收到“确认提交”的消息后,会更新浏览器的状态,包括安全状态、地址栏的URL、前进后退的历史状态,并更新Web页面。
这也解释了为什么在浏览器地址栏输入一个URL后,原页面没有立马消失,而是要加载一会才更新页面。
至此,一个完整的导航流程就走完了,之后就进入渲染阶段
渲染过程涵盖了从用户发起请求到提交文档给渲染进程的中间所有阶段。
五. 渲染阶段
文档被提交,渲染进程便开始页面解析和子资源加载。渲染流程参考下一篇文章。
文章内容参考极客时间 李兵老师的浏览器工作原理与实践课程。