# 发生了什么
输入 URL 回车到页面展示中间发生了什么?
- 输入信息处理
- DNS 查询
- TCP 连接
- 发送请求
- 接受响应
- 渲染页面
# 输入信息处理
处理输入信息,URL 解析。
检查用户输入
当用户在地址栏中输入一个查询关键字时,地址栏会判断输入的关键字是搜索内容,还是请求的 URL。根据输入内容进行自动完成,字符编码等。此外还有安全检查,访问限制等操作。如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的 URL。如果判断输入内容符合 URL 规则,比如输入的是 time.geekbang.org,那么地址栏会根据规则,把这段内容加上协议,合成为完整的 URL。
beforeunload 事件
当用户输入关键字并键入回车之后,这意味着当前页面即将要被替换成新的页面,不过在这个流程继续之前,浏览器还给了当前页面一次执行 beforeunload 事件的机会,beforeunload 事件允许页面在退出之前执行一些数据清理操作,还可以询问用户是否要离开当前页面,比如当前页面可能有未提交完成的表单等情况,因此用户可以通过 beforeunload 事件来取消导航,让浏览器不再执行任何后续工作。
浏览器进入加载状态
当浏览器刚开始加载一个地址之后,标签页上的图标便进入了加载状态。但此时浏览器中页面显示的依然是之前打开的页面内容,并没立即替换为新的页面。因为需要等待提交文档阶段,页面内容才会被替换。
# DNS 查询
发送到网络进程
浏览器进程会通过进程间通信(IPC)把 URL 请求发送至网络进程。
检查缓存
网络进程会查找本地缓存是否缓存了该资源。如果有缓存资源,那么直接返回资源给浏览器进程(浏览器缓存中的强制缓存),若无缓存,则直接进入网络请求流程。
这期间牵扯到浏览器缓存机制,具体翻阅 浏览器缓存
DNS 解析
对 URL 进行 DNS 解析,以获取请求域名的服务器 IP 地址和端口号。如果没有端口号,http 默认80,https 默认 443 如果请求协议是 HTTPS,那么还需要建立 TLS/SSL 连接。
这期间牵扯到 DNS 解析过程、DNS的递归与迭代查询,具体翻阅 DNS 域名系统
# 建立 TCP 连接
首先,判断是不是 https 的,如果是,则 HTTPS 其实是 HTTP + SSL / TLS 两部分组成,也就是在 HTTP 上又加了一层 处理加密信息的模块。服务端和客户端的信息传输都会通过 TLS 进行加密,所以传输的数据都是加密后的数据。
进入 TCP 队列(单个域名 TCP 连接数量限制),通过 三次握手机制 与服务器建立连接。Chrome 有个机制,同一个域名同时最多只能建立 6 个 TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。如果当前请求数量少于 6 个,会直接建立 TCP 连接。
这期间牵扯到 TCP 三次握手和四次挥手、HTTP2、TSL/SSL 等网络知识,具体翻阅 传输层 TCP 协议 等文章。
# 发送请求
浏览器端会构建请求行(方法、URL、协议)、请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,然后向服务器发送构建的请求信息。
- http 请求加上 TCP 头部——包括源端口号、目的程序端口号和用于校验数据完整性的序号,向下传输
- 网络层在数据包上加上IP头部——包括源 IP 地址和目的 IP 地址,继续向下传输
- 底层通过物理网络传输给目的服务器主机
# 接受响应
服务器接收到请求信息后,会根据请求信息生成响应数据(包括响应行、响应头和响应体等信息),并发给网络进程。
- 服务器主机网络层接收到数据包,解析出 IP 头部,识别出数据部分,将解开的数据包向上传输到传输层
- 服务器主机传输层获取到数据包,解析出 TCP 头部,识别端口,将解开的数据包向上传输到应用层
- 应用层 HTTP 解析请求头和请求体,如果需要重定向,HTTP 直接返回 HTTP 响应数据的状态 301 或者302,同时在响应头的 Location 字段中附上重定向地址,浏览器会根据 状态码 和 Location 进行重定向操作;如果不是重定向,首先服务器会根据请求头中的 If-None-Match 的值来判断请求的资源是否被更新,如果没有更新,就返回 304 状态码,相当于告诉浏览器之前的缓存还可以使用,就不返回新数据了;否则,返回新数据,200 状态码,并且如果想要浏览器缓存数据的话,就在相应头中加入字段:Cache-Control:Max-age=2000。响应数据又顺着应用层-传输层-网络层-网络接口层-网络接口层-网络层-传输层-应用层的顺序返回到网络进程。
是否断开连接
数据传输完成,TCP 四次挥手断开连接。如果,浏览器或者服务器在 HTTP 头部加上Connection:Keep-Alive,TCP 就一直保持连接。保持 TCP 连接可以省下次需要建立连接的时间,提升资源加载速度。
重定向
在接收到服务器返回的响应头后,网络进程开始解析响应头,如果发现返回的状态码是 301 或者 302,那么说明服务器需要浏览器重定向到其他 URL。这时网络进程会从响应头的 Location 字段里面读取重定向的地址,然后再发起新的 HTTP 或者 HTTPS 请求,一切重新开始。如果响应行是 200,那么表示浏览器可以继续处理该请求。
响应数据类型处理
浏览器会根据 HTTP 头中 Content-Type 字段来判断服务器返回的响应体数据是什么类型并根据类型决定如何显示响应体的内容。如果 Content-Type 字段的值被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该 URL 请求的导航流程就此结束。但如果是 HTML,网络进程则会通知浏览器进程准备渲染进程进行渲染。
# 渲染页面
# 准备渲染进程
浏览器进程检查当前 URL 是否和之前打开的渲染进程根域名是否相同,如果相同则复用原来的进程,如果不同则开启新的渲染进程。
# 提交文档
浏览器会发出提交文档
的消息给渲染进程,渲染进程接收到消息后,会和网络进程建立传输数据的管道
,文档数据传输完成之后,渲染进程会返回确认提交
的消息给浏览器进程;(文档指的是 URL 请求的响应体)
注意
网络进程向渲染进程提交文档,是边下载边传递给渲染进程解析的,接收到第一批数据,便开始做 DOM 解析了!即提交文档后便开始进行解析 DOM,解析 CSS,生成布局树,绘制等操作。
# 更新浏览器界面状态
浏览器进程在收到确认提交
的消息后,会更新浏览器界面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面。此时的 web 页面是空白页。
# 渲染文档
渲染进程对文档进行页面解析和子资源加载,HTML 通过 HTML 解析器转成 DOM Tree,CSS 按照 CSS 规则和 CSS解释器转成 CSSOM TREE,两个 tree 结合,形成 render tree(不包含HTML的具体元素和元素要画的具体位置),通过 Layout 可以计算出每个元素具体的宽高颜色位置,结合起来,开始绘制,最后显示在屏幕中新页面显示出来。这期间牵扯到浏览器渲染流程,具体翻阅 浏览器渲染
← TypeScript HTTP 前世今生 →