1. HTTP 的版本
1.1 HTTP/0.9(20 世纪 90 年代初)
- 采用纯文本格式
- 由于最初设想的系统里的文档都是只读的,所以只允许
GET
动作从服务器拉取 HTML 数据 - 响应请求后立即关闭连接
1.2 HTTP/1.0(1996 正式发布)
在 0.9 的基础上,做了下面改动:
- 增加了 HEAD、POST等新方法
- 增加了响应状态码,标记可能的错误原因
- 引入了协议版本号概念
- 引入了 HTTP Header 概念,让 Http 处理请求和响应更加容易
- 传输协议不再仅限于文本
但 HTTP 并不是一个标准,而只是一个参考文档,不具有实际的约束力,相当于一个“备忘录”。
1.3 HTTP/1.1(1999 发布 RFC 文档)
在 1.0 的基础上进行了小幅的修正,主要区别是:1.1 是一个“正式的标准”。
HTTP/1.1 的主要改动有:
- 增加了 PUT、DELETE 等新的方法
- 增加了缓存管理和控制
- 明确了连接管理,允许持久连接
- 允许响应数据分块(chunked),利用数据大文件
- 强制要求 Host 头,让互联网主机托管成为可能
1.4 HTTP/2.0(2015 年正式发布)
基于 GOOGLE 开发的 SPY 协议而来。主要特点为:
- 二进制协议,不再是纯文本
- 可发起多个请求,废弃了 1.1 里的管道
- 使用专用算法压缩头部,减少数据传输量
- 允许服务器主动向客户端推送数据
- 增强了安全性,要求加密通信
1.5 HTTP/3.0(2018 年进入标准化制定阶段)
基于 GOOGLE 的 QUIC 协议而来。
2. 什么是 HTTP
2.1 HTTP 解释
HTTP(Hyper Text Transfer Protocol):超文本传输协议,从字面上来看,用来传输超文本的一个协议。
详细说明
HTTP 是一个计算机世界里专门用来在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。
协议的特点
- 协议必须要有两个或以上的参与者,也就是“协”
- 协议是对参与者的一种行为约束和规范,也就是“议”
2.2 HTTP 的特点
- HTTP 使用计算机能够理解的语言确立了计算机之间交流通信规范,以及相关的各种控制和错误处理方式
- HTTP 是一个计算机世界里专门用来在两点之间传输数据的约定和规范
- HTTP 可以传输各种类型的资源,如:图片、音频、视频等
3. HTTP 应用之 CDN 加速
3.1 互联网(Internet)和 HTTP 的关系
HTTP 所对应的 WWW(万维网)服务只是互联网的一个“子集”。除了 WWW 服务之外,还是 SMTP/POP3 电子邮件、FTP 文件下载、SSH 安全登录等多种服务,共同构成了今天的互联网。
3.2 CDN
CDN(Content Delivery Network)中文名称为“内容分发网络”,它应用了 HTTP 协议里的缓存和代理技术,作用是:代替源站响应客户端的请求。
好处
- 为源站分摊请求处理
- 寻找离用户最近节点,大幅缩短响应时间
局限
CDN 无法缓存由 PHP、JAVA 等后台服务生成的页面,只能从目标网络获取。
4. 常见协议与 HTTP 的关系
4.1 TCP/IP
TCP/IP 是一系列协议的统称,其中最核心有就是 TCP 和 IP 协议。除此之外,还有 UDP、ICMP、ARP 等等,共同构建了一个复杂蛤有层次的协议栈。
IP 协议
主要目的是解决寻址和路由问题,以及在两点之间传输数据包。V6 版本的地址协议使用 8 组“:”分隔的十六进制数作为地址,其容量为 2^128
次方。
TCP 协议
TCP(Transfer Control Protocol)协议:传输控制协议,它位于 IP 协议之上,基于 IP 协议提供可靠的、字节流形式的通信,是 HTTP 协议实现的基础。
4.2 DNS
有了 IP 地址,还要 DNS 做什么?
由于 IP 地址不方便人类的记忆,于是,使用 DNS 技术,通过有意义的字母或数字来代替无意义的 IP 地址来方便人类记忆。
在访问过程中,先将域名解析成 IP 地址,然后再进行数据的传输。
4.3 URI/URL
URI(Uniform Resource Identifier):中文名称统一资源标识符,用它来唯一地标记互联网上的资源。
URL(Uniform Resource Locator):中文名称统一资源定位符,其是 URI 的一个子集。
4.4 HTTPS
HTTPS:是一个负责加密通信的安全协议,建立在 TCP/IP 之上,所以也是可靠的传输协议。
SSL(Secure Socket Layer):由网景公司开发。
TLS(Transfer Layer Security):SSL 发展到标准化后改名为 TLS。
4.5 代理
代理(Proxy):是 HTTP 协议中请求方和响应方中间的一个环节,作为“中转站”,即可以转发客户端的请求,也可以转发服务器的应答。
代理的种类
- 匿名代理:完全“隐匿”了被代理的机器,外界看到的只是代理服务器
- 透明代理:它在传输过程中是“透明开放”的,外界既知道代理,也知道客户端
- 正向代理:代替客户端向服务端发送请求
- 反向代理:代替服务器响应客户端的请求
基于代理的服务
- 负载均衡:把访问请求均匀分散到多台机器,实现访问集群化
- 内容缓存:类似 CDN,缓存数据,减轻服务器压力
- 安全防护:隐匿 IP,使用 WAF 等工具抵御网络攻击,保护代理服务器
- 数据处理:数据压缩,加密等额外功能
5. TCP/IP 和 ISO 协议栈
5.1 TCP/IP 协议栈
链路层:负责在以太网、WIFI 这样的底层网络中传输原始数据包,工作在网卡这个层次,使用 MAC 地址来标记网络上的设备。
网际层/网络互联层:用 IP 地址取代 MAC 地址,把许多局域网、广域网连接成一个虚拟的巨大网络。
传输层:保证数据在由 IP 地址标记的两点之间“可靠”传输。在这一层工作的主要是 TCP 和 UDP。TCP 是有状态的协议,需要通过三次握手与对方建立连接后,才能发送数据,从而保证数据不丢失,不重复。而 UDP 是无状态的,不用事先连接,也不保证数据一定发送给对方。TCP 的数据是连续的“字节流”,有先后顺序;而 UDP 则是分散的小数据包,是顺序发,乱序收。
应用层:面向具体应用的协议。如:Telnet、SSH、FTP、SMTP/POP 等
各层数据包的区分
- MAC 层的传输单位是帧(frame)
- IP 层传输单位是包(Package)
- TCP 层传输单位是段(segment)
- HTTP 层传输单位是消息或报文(message)
这几种无本质区别,都是数据包。
TCP、UDP 数据包的区别
TCP 建立连接后,数据在该连接上流动,可以是双向的,没有边界。而 UDP 是以独立的数据包来发送数据,每个包中都包含源 IP 地址和目标 IP 地址。
5.2 OSI(网络分层模型)
全称为:开放式系统互联通信参考模型。这个是 ISO 标准化组织为了统一各网络协议而制定出来的。比 TCP/IP 要晚,而且只是停留在理论层面上。事实上,互联网上应用的还是 TCP/IP 这一套协议栈。
物理层:网络的物理形式,如:光缆、网卡等
数据链路层:相当于 TCP/IP 的链接层
网络层:相当于 TCP/IP 的网际层
传输层:相当于 TCP/IP 的传输层
会话层:维护网络中的连接状态,保持会话和状态
表示层:把数据转换为合适,可以理解的语法和语义
应用层:面向具体的应用传输数据
5.3 OSI 和 TCP/IP 的映射关系
四层负载均衡
是指工作在传输层上,基于 TCP/IP 协议的特性,通过 IP、端口号等实现对后端服务器的负载均衡。
七层负载均衡
是指工作在应用层上,看到的是 HTTP 协议,解析 HTTP 报文里的 URI,再用适当的策略转发给后端服务器。
TCP/IP 数据包流转图
6. DNS
6.1 DNS 三层系统结构
- 根域名服务器(Root DNS Server):管理顶级域名服务器,返回
.com
、.cn
等顶级域名服务器的 IP 地址 - 顶级域名服务器(Top-level DNS Server):管理各自域名下的权威域名服务器,比如:com 顶级域名服务器可以返回
baidu.com
域名服务器的 IP 地址 - 权威域名服务器(Authoritative DNS Server):管理自己域名下主机的 IP 地址,比如:
badu.com
权威域名服务器可以返回www.baidu.com
的 IP 地址
6.2 如何保证 DNS 的服务稳定运行
1. 缓存
浏览器缓存 -> 操作系统缓存 -> 本地 hosts 文件 -> 非权威服务器缓存 -> 根域名服务器缓存 -> 顶级域名服务器缓存 -> 权威域名服务器缓存
6.3 基于 DNS 的负载均衡
- 一个域名可以对应多台主机,客户端收到多个 IP 地址后,就可以自己使用轮询算法依次向服务器发起请求,实现负载均衡。也就是通过客户端来实现负载均衡
- 域名解析可以配置内部的策略,返回离客户端最近的主机,或者返回当前服务质量最好的主机,这样在 DNS 服务端把请求分发到不同的服务器,实现负载均衡
6.4 恶意 DNS 服务器
- 域名屏蔽:对域名直接不解析,返回错误,让你无法拿到 IP 地址
- 域名劫持:也叫“域名污染”,你要访问 A 网站,但 DNS 给了你 B 网站
7. 一次 HTTP 请求的全过程
1. 先进行 TCP 三次握手,建立连接
浏览器使用 52085,服务器使用 80 端口,经过 SYN、SYN/ACK、ACK 的三个包之后,浏览器与服务器的 TCP 连接就建立起来了。
2. 浏览器发送 HTTP 请求报文
通过 TCP 连接发送了一个 GET / HTTP/1.1
请求报文。
3. 服务器收到请求后,立即回复 TCP ACK 确认已收到请求
上图中的第 5 个包,通过 TCP 协议层确认收到浏览器发过来的请求,这个 TCP 层的响应是不会传递到上层的。
4. 服务器对请求进行处理,通过 HTTP 报文格式进行响应
上图中的第 6 个包。
5. 浏览器接收到服务器响应后,立即回复 TCP ACK 确认,表示已经收到这个响应了
上图中的第 7 个包。
6. 浏览器通过调用排版引擎,JS 引擎等对服务器的响应进行渲染
第 8 ~ 11 这 4 个包是浏览器在渲染 JS 的过程中,发现当前页面需要加载 favicon.ico
这个资源,所以,又发送 HTTP 请求到服务器获取相应资源,而服务器上没有该资源,所以,返回了 Not Found
。
7.1 通信交互图
8. HTTP 报文
8.1 HTTP 报文结构
HTTP 协议规定,必须要有 Header,而且 Header 后跟必须有一个空行(CRLF),但是实体部分不是必须的。
请求行
请求方法:是一个动词,表示对资源的动作。
请求目标:通常是一个 URI,标记请求方法要操作的资源。
版本号:表示报文使用的 HTTP 版本。
中间用“空格”隔开,并通过“CRLF”换行表示结束。
状态行
版本号:表示 HTTP 使用的协议版本。
状态码:一个三位数,用代码的形式表示处理的结果。
原因:状态码的文字描述。
头部字段
请求行或状态行再加上头部字段集合就构成了 HTTP 报文里完整的请求头或响应头。也就是:
请求头或响应头 = 请求行或响应行 + 头部字段组成。
请求头或响应头的结构
HTTP 请求头里唯一必须出现的字段
Host: www.baidu.com
Host 字段告诉服务器请求应该由哪个服务器处理,当一台计算机中托管了多个虚拟主机时,服务器端就需要使用 Host 字段来选择转发给哪一个虚拟主机。
主要用于区分 IP 地址相同但域名不同的网站。
Content-lengh 和 chunked
Content-lengh:用来表示实体 body 数据长度。如果没有这个字段的话,说明实体字段是不定长的,需要使用 chunked 方法分段传输。
8.2 HTTP GET 请求报文
9. 使用 Telnet 测试 HTTP 通信过程的方法
- 运行 telnet 工具
- 输入
open + 域名 + 端口号
10. 请求方法
10.1 请求方法种类
- GET:获取资源,读取或者下载数据
- HEAD:获取资源的元信息,也就是只有响应头,而没有实体 body。比如:检查文件是否存在;检查文件是否有新版本等操作
- POST:向资源提交信息,相当于写入或上传数据,数据放在报文的实体 body 里,相比于 PUT,POST 常常有“新建”的含义
- PUT:类似 POST,相比于 POST,PUT 常常有“修改”的含义
- DELETE:删除资源
- CONNECT:建立特殊的连接隧道,要求服务器为客户端和另一台远程服务器建立一条特殊的连接隧道,此时,WEB 服务器充当“代理”角色
- OPTIONS:列出对资源实行的方法
- TRACE:追踪请求/响应的传输路径
10.2 安全和幂等
HTTP 中的安全
在 HTTP 协议里的安全指的是:请求方不会“破坏”服务器上的资源,即不会对服务器上的资源造成实质的修改。所以,只有 GET 和 HHEAD 操作是安全的。
而 POST/PUT/DELETE 这几个请求方法是不安全的。
HTTP 中的幂等
所谓“幂等”就是多次执行相同的操作,结果也都是相同的,即多次“幂”之后“相等”。
同样的,GET 和 HEAD 请求方法即是安全的也是幂等的,DELETE 可以多次删除同一个资源,效果都是“资源不存在”,所以也是幂等的。
POST 的定义是“新增或提交数据”,多次提交会创建多个资源,所以不是幂等的;而 PUT 的定义是“替换或更新数据”,多次更新一个资源,所以是幂等的。
说明
此文是根据罗剑锋透视 HTTP 协议相关专栏内容整理而来,非原创。