浏览器系列 -- 从URL到网页加载

382 阅读6分钟

总体来说分为以下几个过程:

  1. 缓存解析
  2. DNS解析
  3. TCP连接
  4. 浏览器发送HTTP请求
  5. 服务器处理请求并返回HTTP报文
  6. 浏览器解析渲染页面
  7. TCP断开连接

具体过程

1. 缓存解析

先去缓存里面找资源,如果缓存里面有资源直接在缓存里面拿就好

缓存资源寻找路线:浏览器缓存离线缓存内存缓存硬盘缓存)-> 各种中间代理服务器的缓存(如:CDN缓存

浏览器缓存机制详见 浏览器系列 -- 浏览器缓存

CDN缓存机制详见 浏览器系列 -- CDN 缓存

2. DNS 解析

  • DNS(Domain Name System, 域名系统),是域名和IP地址相互映射的一个分布式数据库
  • DNS 解析就是从域名映射到IP地址的过程
  • 另外,如果有些网站已经访问过了,下次访问时浏览器会依次从浏览器缓存系统缓存路由器缓存ISP缓存根域名服务器顶级域名服务器主域名服务器里面找IP地址,所以下次访问速度更快
  • 另外有些HTTP网页会自动做DNS预解析,就是提前解析之后可能会用到的域名,并将解析结果缓存到系统缓存中,缩短DNS解析时间,提高网站的访问速度(<meta><link>标签进行控制)

关于DNS的详细解读见 浏览器系列 -- DNS 解析及预解析

3. TCP 连接

知道了服务器的 IP 地址,下面便开始与服务器建立连接了

这里要提醒一点,Chrome 在同一个域名下要求同时最多只能有 6 个 TCP 连接,超过 6 个的话剩下的请求就得等待。

假设现在不需要等待,我们进入了 TCP 连接的建立阶段。首先看一下什么是 TCP:

TCP是一种`面向连接`的、`可靠`的、基于`字节流``传输层通信协议`

TCP连接的建立和断开需要经历以下三个过程:

  1. 通过三次握手(即总共发送3个数据包确认已经建立连接)建立客户端和服务器之间的连接。
  2. 进行数据传输。每次数据传输都是通过数据包的形式来传输的。而且每次接收方接收到数据包后必须要向发送方确认数据包校验),如果发送方没有收到这个确认的消息,就判定为数据包丢失,并重新发送该数据包
发送过程有个优化策略:就是`把大的数据包拆成一个个小包`,依次传输到接收方,接收方按照小包的顺序`组装`成完整数据包
这样就不会说大包整个丢失了还要`重新传输整个大包`,而只是`针对某个丢失的小包`进行重新传输而已
  1. 断开连接的阶段。数据传输完成,现在要断开连接了,通过四次挥手来断开连接。 从这里可以看出TCP 协议是如何保证信息传输的可靠性:一是三次握手确认连接,二是数据包校验保证数据到达接收方,三是通过四次挥手断开连接

TCP 连接的深入解读见 计算机网络系列 -- TCP的三次握手、四次挥手

4. 浏览器和服务器之间的交互

浏览器和服务器之间进行数据传输。每次数据传输都是通过数据包(请求包+响应包)的形式来传输的。

其中浏览器发送HTTP请求是请求包,服务器回应是数据包称为响应包

image.png

4.1. 浏览器发送HTTP请求

HTTP请求报文

现在TCP连接建立完毕,浏览器可以和服务器开始通信,即浏览器开始发送 HTTP 请求。其中请求中要携带三样东西:请求行请求头请求体 image.png

  • 请求行 Line (请求方法method + HTTP协议版本
// 请求方法是GET,路径为根路径,HTTP协议版本为1.1
GET / HTTP/1.1
// 请求方法 + HTTP协议版本
POST / HTTP/1.1

GETPOST的区别 详见计算机网络系列 -- GET和POST的区别

  • 请求头 Header
Accept:  /* 浏览器支持的 MIME 类型 */  text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br /* 浏览器支持的压缩编码 */
Accept-Language: zh-CN,zh;q=0.9 /* 浏览器支持的语言 */

Cache-Control: no-cache /* 不建立缓存 */
If-Modified-Since: xxx /* 与服务器的 Last-Modified 对线 */
If-None-Match: xxx /* 与服务器的 ETag 对线 */
Pragma: no-cache

Cookie: /* 浏览器想服务器发送的cookie内容 */
Connection: keep-alive /* 表示建立持久连接 */
Host: www.baidu.com /* 域名 */
Upgrade-Insecure-Requests: 1
User-Agent: /* 用户代理 */  Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
  • 请求体 Body

请求体只有在POST方法才存在,常见的场景是表单提交

关于HTTP/HTTPS 请求详细解读见 计算机网络系列 -- HTTP

4.2. 服务器响应请求

HTTP响应报文

HTTP 请求到达服务器,服务器进行对应的处理。最后要把数据传给浏览器,也就是返回网络响应,跟请求部分类似,网络响应具有三个部分:响应行响应头响应体 image.png

  • 响应行 Line (HTTP协议版本 + 状态码 + 状态描述
// HTTP协议版本是1.1,状态码是200,状态描述是 OK
HTTP/1.1 200 OK

其它状态码详见 计算机网络系列 -- HTTP状态码

  • 响应头 Header
Cache-Control: no-cache
Connection: keep-alive /* 表示建立持久链接 */
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Wed, 04 Dec 2019 12:29:13 GMT /* 响应时间 */
Age:/* 响应持续时间 */
Server: apache /* 服务器应用程序软件的名称和版本 */
Set-Cookie: rsv_i=xxx; path=/; domain=.baidu.com /* 服务器下发cookie */
  • 响应体 Body 响应完成之后怎么办?TCP 连接就断开了吗? 不一定。这时候要判断Connection字段, 如果请求头或响应头中包含Connection: Keep-Alive,表示建立了持久连接,这样TCP连接会一直保持,之后请求统一站点的资源会复用这个连接。 否则断开TCP连接,请求-响应流程结束

5. 浏览器渲染页面

  1. 在浏览器还没有完全接收 HTML 文件时便开始渲染、显示网页;
  2. 在执行 HTML 中代码时,根据需要,浏览器会继续请求图片、CSS、JavsScript等文件,过程同请求 HTML 浏览器渲染具体过程见 浏览器系列 -- 渲染原理及过程

6. TCP 挥手断开连接

  1. 主机向服务器发送一个断开连接的请求(不早了,我该走了);
  2. 服务器接到请求后发送确认收到请求的信号(知道了);
  3. 服务器向主机发送断开通知(我也该走了);
  4. 主机接到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开连接; TCP 断开连接详细解读见 计算机网络系列 -- TCP的三次握手、四次挥手

如何优化页面加载

提升页面加载速度真的很重要,详细见 浏览器系列 -- 优化页面加载