总体来说分为以下几个过程:
- 缓存解析
- DNS解析
- TCP连接
- 浏览器发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 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连接的建立和断开需要经历以下三个过程:
- 通过三次握手(即总共发送
3个数据包
确认已经建立连接)建立客户端和服务器之间的连接。 - 进行
数据传输
。每次数据传输都是通过数据包
的形式来传输的。而且每次接收方接收到数据包后必须要向发送方确认
(数据包校验),如果发送方
没有收到这个确认的消息,就判定为数据包丢失
,并重新发送
该数据包
发送过程有个优化策略:就是`把大的数据包拆成一个个小包`,依次传输到接收方,接收方按照小包的顺序`组装`成完整数据包
这样就不会说大包整个丢失了还要`重新传输整个大包`,而只是`针对某个丢失的小包`进行重新传输而已
- 断开连接的阶段。数据传输完成,现在要断开连接了,通过
四次挥手
来断开连接。 从这里可以看出TCP 协议是如何保证信息传输的可靠性:一是三次握手确认连接,二是数据包校验
保证数据到达接收方,三是通过四次挥手
断开连接
TCP 连接的深入解读见 计算机网络系列 -- TCP的三次握手、四次挥手
4. 浏览器和服务器之间的交互
浏览器和服务器之间进行数据传输
。每次数据传输都是通过数据包
(请求包+响应包)的形式来传输的。
其中浏览器发送HTTP请求是请求包
,服务器回应是数据包称为响应包
4.1. 浏览器发送HTTP请求
HTTP请求报文
现在TCP连接建立完毕,浏览器可以和服务器开始通信,即浏览器开始发送 HTTP 请求。其中请求中要携带三样东西:请求行
、请求头
和请求体
- 请求行 Line (
请求方法method
+HTTP协议版本
)
// 请求方法是GET,路径为根路径,HTTP协议版本为1.1
GET / HTTP/1.1
// 请求方法 + HTTP协议版本
POST / HTTP/1.1
GET
和POST
的区别 详见计算机网络系列 -- 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 请求到达服务器,服务器进行对应的处理。最后要把数据传给浏览器,也就是返回网络响应
,跟请求部分类似,网络响应具有三个部分:响应行
、响应头
和响应体
- 响应行 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. 浏览器渲染页面
- 在浏览器还没有完全接收 HTML 文件时便开始渲染、显示网页;
- 在执行 HTML 中代码时,根据需要,浏览器会继续请求图片、CSS、JavsScript等文件,过程同请求 HTML 浏览器渲染具体过程见 浏览器系列 -- 渲染原理及过程
6. TCP 挥手断开连接
- 主机向服务器发送一个断开连接的请求(不早了,我该走了);
- 服务器接到请求后发送确认收到请求的信号(知道了);
- 服务器向主机发送断开通知(我也该走了);
- 主机接到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开连接; TCP 断开连接详细解读见 计算机网络系列 -- TCP的三次握手、四次挥手
如何优化页面加载
提升页面加载速度真的很重要,详细见 浏览器系列 -- 优化页面加载