计算机网络⑤应用层:HTTP协议(todo)
HTTP 协议
超文本传输协议(Hyper Text Transfer Protocol),是 TCP/IP 协议族的一个子集。
1、基础知识
1.1、网络和 TCP/IP
回顾一下基础知识:
- 网络发展阶段
- 协议:分组交换、标准化
- TCP/IP 协议分层
- 应用层
- 传输层:TCP、UDP
- 网络层:IP
- 数据链路层、物理层
- 其它知识点:网络组成、地址、首部等
1.2、URI 和 URL
| URI | URL | |
|---|---|---|
| 全称 | 统一资源标识符,Uniform Resource Identifier | 统一资源定位符,Uniform Resource Locater |
| 含义 | 唯一标识资源 | 互联网中资源的位置 |
| 说明 | 只对资源进行标识,而不进行定位 | 不仅对资源进行标识,还具体到资源位置 |
| 实例 | http://www.abc.com唯一标识资源,但没有定位资源位置 |
http://www.abc.com/image/1.png唯一标识资源,也定位资源位置 |
结论:URI 和 URL 是包含关系,而不是并列关系。
- URI 是一个抽象概念,可以有不同实现形式。但只要能唯一标识资源的就可以称作 URI。
- URL 是 URI 的实现,在 URI 的基础上定位了资源位置。
- 只要是 URL,就一定是 URI。
1.3、HTTP 版本
| 时间 | 标准 | 连接方式 | |
|---|---|---|---|
| HTTP/0.9 | 1990 年问世 | 未成为标准 | - |
| HTTP/1.0 | RFC1945:1996 年 5 月 | 初期标准 | 每次 HTTP 通信(一次请求和响应)使用新的 TCP 连接 |
| HTTP/1.1 | RFC2068:1997 年 1 月 RFC2616:修订版 |
目前主流标准 | 持久连接:在一个 TCP 连接上发送多个请求和响应 |
1.4、HTTP 相关协议
-
DNS:负责域名解析
-
:面向连接的、可靠的流协议
-
:实现端到端通信
2、HTTP
HTTP 协议 是 TCP/IP 协议族的一个子集。
-
用于 C/S 通信,通过请求和响应的交换达成通信。
-
客户端发出请求,服务器端响应请求并返回。
2.1、无状态协议
HTTP 不保存通信状态,对于发送过的请求或响应都不做持久化处理。
- 每当有新的请求发出,都会有新的响应。
- 目的:减少服务器 CPU 和内存消耗,更快地处理大量事务,确保协议的可伸缩性,
- HTTP/1.1 中引入 Cookie 技术,实现保持状态功能。
Cookie
假设一个场景
Web 页面使用无状态的 HTTP 协议,登录状态不会被保存。
导致每次跳转页面都需要再次登录,或者每次都在请求报文中附加参数来管理登录状态。
引入 Cookie 技术
在保留 HTTP 无状态协议特性的同时,实现了保持状态功能。
Cookie 技术,通过在请求和响应报文中写入 Cookie 信息,来控制客户端的状态。
- 服务器端:在响应报文中添加 Set-Cookie 首部字段,通知客户端保存 Cookie。
- 客户端:将 Cookie 信息保存在本地,在请求报文中添加 Cookie 值。
Cookie 交互
报文信息(有关报文的详解,见下一节)
-
请求报文:无 Cookie 信息

-
响应报文:生成 Cookie 信息

-
请求报文:有 Cookie 信息

2.2、持久连接
持久连接(HTTP keep-alive),HTTP/1.1 的默认连接
- HTTP/1.0:每进行一次 HTTP 通信,就要建立和断开一次 TCP 连接。
- HTTP/1.1:持久连接。只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
- 减少了 TCP 连接的重复建立和断开所造成的开销。
- 减轻服务器端的负载。
管线化(流水线式)
管线化:无需等待响应,即可直接发送下一个请求。(并行发送)
没有使用管线化技术的情况下,需要等待上一个响应,才能发送新的请求。
2.3、范围请求
在下载大文件时如果遇到网络中断,就必须重头开始。
因此需要一种恢复机制,而实现恢复机制的前提是范围请求。
- 恢复:能在下载中断处恢复下载。
- 范围请求(Range Request):指定资源的下载范围。
- 请求:使用 Range 首部字段,指定资源的 byte 范围;
- 响应:状态码 206(Partial Content)
2.4、内容协商
内容协商(Content-Negotiation):当浏览器的默认语言不同,访问相同 URI 的页面时,会显示对应语言的 Web 页面。
内容协商机制:就响应的资源内容进行交涉,提供给客户端最为合适的资源。
- 判断基准:响应资源的语言、字符集、编码方式等;
- Accept
- Accept-Charset
- Accpet-Encoding
- Accpet-Language
- Content-Language
- 类型
- 服务器驱动类型:服务器端进行,以请求报文的首部字段未参考;
- 客户端驱动协商:客户端进行,从浏览器的可选项列表中选择。
- 透明协商:服务器驱动和客户端驱动的结合。
3、HTTP 报文
HTTP 报文:用于 HTTP 协议交互的信息。
- 报文:由多行数据构成的字符串文本(用 CR+LF 作换行符)
- 结构
- 报文首部:请求或响应的内容及属性。
- 空行:CR+LF
- 报文主体:可选,表示应被发送的数据(实体主体)
请求报文
首部由请求行和首部字段组成。
响应报文
首部由响应行和首部字段组成。
实例
3.1、报文首部
3.1.1、请求行:方法
请求报文首部——请求行
方法:使指定请求 URI 的资源,按期望产生某种行为。
- 即:客户端使用不同的方法,向指定 URI 发出请求报文,服务器会采取不同的行为。
- 方法名区分大小写,要用大写字母。
HTTP 1.0 和 HTTP/1.1 支持的方法
共有的方法:GET、POST、PUT、HEAD、DELETE
-
HTTP/1.0:LINK 和 UNLINK,在 1.1 已被废弃
-
HTTP/1.1:OPTION、TRACE、CONNECT
HTTP/1.1
下面详细介绍 HTTP/1.1 中的方法。
| 意图 | 含义 | 注意 | |
|---|---|---|---|
| GET | 获取资源 |
已被 URI 识别的资源,经服务器端解析后返回响应内容。 | 请求的资源是文本则直接返回,是 CGI 等程序则返回执行结果。 |
| POST | 传输实体主体 | ||
| PUT | 传输文件 | 在请求报文中包含文件内容,将文件保存到指定 URI | 不带验证机制,存在安全性问题 |
| HEAD | 获取报文首部 | 类似 GET,但只获取报文首部 | 不获取报文主体部分,通常用于确认 URI 有效性、资源更新的日期时间等 |
| DELETE | 删除文件 | 与 PUT 相反,删除指定 URI 的资源 | 不带验证机制,存在安全性问题 |
| OPTIONS | 询问支持的方法 | 查询指定 URI 支持的请求方法 | 即向服务器询问,某个 URI 支持使用哪些方法对其请求 |
| TRACE | 追踪路径 | 让服务器将请求通信环回给客户端 | 不常用,而且容易引发 XST(Cross-Site Tracing,跨站追踪) |
| CONNECT | 使用隧道协议连接代理 | 在与代理服务器时建立隧道,用隧道协议进行 TCP 通信 | 主要使用 SSL 和 TLS 协议,将通信内容加密后经网络隧道传输 |
3.1.2、响应行:状态码
响应报文首部——响应行
状态码:表示请求的返回结果(服务器正常处理请求 / 出现错误)
2XX:成功
表明请求被正常处理。
- 200 OK
- 204 No Content:不含报文主体
- 206 Partial Content:范围请求
3XX:重定向
浏览器需要执行某些特殊的处理以正确处理请求。
- 301 Moved Permanently:永久性重定向
- 302 Found:临时性重定向
- 303 See Other:资源存在另一个 URI,且需要按 GET 方式访问
- 304 Not Modified:请求未满足条件(权限)
- 307 Temporary Redirect:不会从 POST 变成 GET 请求
说明:
-
在 301 和 302 标准中,禁止将 POST 方法改成 GET。
-
在 303 标准中,应当用 GET 方式访问资源的另一个 URI,而不是 POST。
-
但是,几乎所有的浏览器都没有遵守标准,在收到 301、302、303 状态码时,将 POST 改成 GET 并重新发送请求。
-
307 会按照浏览器标准,不会从 POST 变成 GET。
4XX:客户端错误
客户端发生错误
- 400 Bad Request:请求报文中存在语法错误
- 401 Unauthorized:请求未通过 HTTP 认证
- 403 Forbidden:服务器拒绝访问(未获得授权、访问权限不足)
- 404 Not Found:无法找到请求的资源
5XX 服务器错误
服务器发生错误
- 500 Internal Server Error:服务器端在执行请求时发生错误
- 503 Service Unavailable:服务器处于超负载或停机维护
3.1.3、首部字段
请求报文或响应报文——首部字段
请求和响应报文都会使用首部字段,用于传递额外的重要信息。
- 通用首部
- 请求首部、响应报文
- 实体首部
- 其它
// 结构
首部字段名: 字段值
// 例如
Content-Type: text/html
// 可以有多个字段值
Keep-Alive: timeout=15, max=100
种类
HTTP/1.1 规范定义的47 种首部字段
-
通用首部
-
请求首部
-
响应报文
-
实体首部
非 HTTP/1.1 首部字段
在 HTTP 通信中,不限于使用 RFC2616 中定义的 47 中首部字段。
还有 Cookie、Set-Cookie、Content-Disposition 等非正式的首部字段。
类型
HTTP 首部字段分为 2 种类型,依据是使用缓存代理和非缓存代理。
- 端到端首部(End-to-end):会转发给最终接收目标,且必须保存在由缓存生成的响应中。
- 逐跳首部(Hop-by-hop):单次转发有效,因经过缓存或代理后不再转发。
3.2、报文主体
HTTP 的报文主体,用于传输实体主体。
- 报文(message):HTTP 通信的基本单位
- 实体(entity):作为请求和响应的有效载荷数据,由实体首部和实体主体组成。
通常,报文实体就是实体主体。
3.2.1、编码
如果在传输中对实体主体进行编码操作时,以上二者就不是同一个概念。
- 内容编码:用于压缩传输
- 指明应用在实体内容上的编码格式,保持实体信息原样发送;
- 客户端接收并负责解码。
- 分块传输编码:用于分割发送
- 将实体主体分成多个块;
- 客户端接收并负责解码。
3.2.2、多部份集合对象
类似邮件中的 MIME 机制,HTTP 协议也采纳了多部份集合对象。
通常在图片或文本文件上传时使用。
添加 Content-type 首部字段,使用 boundary 字符串划分每个实体。
-
multipart/form-data:Web 表单文件上传
-
multipart/byteranges:多范围内容
4、Web 服务器
HTTP/1.1 允许一台 HTTP 服务器搭建多个 Web 站点,利用了虚拟主机的功能。
- 虚拟主机(Virtual Host):又称虚拟服务器。
- 即使物理层面只有一台服务器,可以“变成”多台服务器。
- 部署在同一个服务器上的站点,具有相同的 IP 地址。
- HTTP 请求报文必须在 Host 首部内完整指定主机名或域名的 URI。
通信数据转发程序
个人理解:代理模式的不同应用场景
-
代理:转发请求和响应
- 透明代理:不对报文作任何加工。反之则称为非透明代理。
- 缓存代理:将资源的副本保存在代理服务器上。
-
网关:转发服务器通信数据,就像自己拥有资源的源服务器
- 能使通信线路上的服务器提供非 HTTP 服务;
- 能在客户端和网关之间的通信线路上加密,提高通信安全性。
-
隧道:在客户端和服务器之间进行中转
- 确保客户端和服务器能进行安全通信。
- 隧道本身不会解析 HTTP 请求。
5、HTTP 缓存
5.1、Cache-Control
通常,客户端不会直接对源服务器发起请求。
在客户端和源服务器之间,使用一个缓存服务器。
-
客户端向缓存服务器发出请求。
-
缓存服务器将请求转发给源服务器,将源服务器的响应内容转发给客户端,并在本地作缓存。
-
下次客户端对相同的资源发起请求时,缓存服务器可以将缓存资源直接返回给客户端,无需再访问源服务器。
通用首部字段:Cache-Control
- 功能:控制缓存的行为。
- 指令参数:参数是可选的,多个参数之间用
,分隔。 - 请求报文和响应报文都可以使用 Cache-Control,具体的指令和用途可能有所不同。
共有的指令
在客户端的请求报文中使用,或在源服务器的响应报文中使用。
功能可能有所不同。
- no-cache:防止使用过期的缓存(而不是不缓存)
- 在请求中使用:客户端不接收缓存过的响应,缓存服务器必须把请求转发给源服务器;
- 在响应中使用:源服务器要求缓存服务器不对资源进行缓存。
- no-store:不缓存
- max-age
- 在请求中使用
- 客户端只接收缓存时间比 max-age 数值小的缓存资源。
- 如果指定 max-age 为 0,则缓存服务器需要将请求转发给源服务器
- 在响应中使用
- 缓存服务器不对资源有效性再作确认。
- max-age 数值为缓存资源的最长保存时间
- 在请求中使用
- no-transform:缓存不能改变实体主体的媒体类型,防止压缩图片等操作
- cache-extension:扩展 Cache-Control 的首部字段内的指令。
缓存请求指令
- max-stale:即使缓存资源过期,也照常接收。
- min-fresh:客户端要求缓存服务器,返回指定时间以内的缓存资源。
- only-if-cached:请求的资源在缓存服务器的本地缓存时,客户端才要求其返回。
(即如果缓存服务器中没有请求资源的缓存,则不会转发请求给源服务器)
缓存响应指令
- public:任何用户都可以使用响应的缓存
- private:指定用户才能使用响应的缓存
- 缓存服务器对特定用户提供资源缓存的服务
- 对其它用户发送的请求,不会返回缓存
- s-maxage:与 max-age 相同,但是 s-maxage 仅用于多用户使用的公共缓存服务器。
- must-revalidate:要求代理在返回缓存资源之前,向源服务器再次验证缓存是否仍有效
- proxy-revalidate:类似 must-revalidate,但只适用于共享缓存,不影响私有缓存。
5.2、todo
6、HTTPS
HTTP Secure,超文本传输安全协议
HTTP 的缺点
- 不无加密:通信使用明文,可能被窃听。
- 无认证:不验证通信方的身份,可能被伪装。
- 无完整性保护:无法证明报文完整性,可能被篡改。
HTTPS
**HTTPS = HTTP + 加密 + 认证 + 完整性保护 **
HTTPS = HTTP + SSL
HTTPS 不是新技术,而是指与 SSL 组合使用的 HTTP。
-
通常,HTTP 与 TCP 直接通信。
-
使用 SSL:HTTP 先与 SSL 通信,再由 SSL 与 TCP 通信。
加密
- 加密的前提:客户端和服务器都具有加密和解密的机制。
- 客户端或服务器,需要将自己的加密方式(即密钥)交给对方。
共享密钥加密(Common crypto system)
在了解公开密钥加密之前,先了解一下共享密钥加密。
共享密钥加密,是指加密和解密使用同一把密钥(对称密钥)。
因此,在将密钥转发给对方时,可能遭遇窃听。
公开密钥加密(Public-key cryptography)
加密方式复杂,更安全,但效率低
公开密钥加密,使用一对密钥:私有密钥和公开密钥(非对称密钥)。
- 私有密钥:不能让其他人获取,用于解密。
- 公开密钥:可以随意发布,用于加密。
密文的发送方,使用对方的公开密钥进行加密处理,接收方使用自己的私有密钥进行解密。
由于

混合加密机制
HTTPS 将两种加密方式并用
-
使用公开密钥加密方式交换密钥
-
使用共享密钥加密方式进行通信。
公开密钥证书
公开密钥加密存在的问题:无法证明公开密钥本身就是真实的,可能被攻击者替换了。
为解决该问题,使用数字证书认证机构(Certificate Authority)及相关机构颁发的公开密钥证书。
认证
认证:为了确认使用者是本人。
HTTP/1.1 的认证方式
- BASIC 认证(基本)
- DIGEST 认证(摘要)
- SSL 客户端认证
- FormBase 认证(基于表单)
- * 还有 Windows 统一认证
BASIC 认证
(Base64 编码)
灵活性、安全性低
-
Base64 编码属于明文,没有加密。
-
无法注销认证。
DIGEST 认证
(质询/响应)
相比 BASIC 认证,密码泄露的可能性降低。

SSL 客户端认证
(客户端证书)
防止由于用户 ID 和密码被盗,导致的第三者冒充。
- 客户端需安装证书,发送请求时将客户端证书的信息发送给服务器。
- 服务器进行验证。
FormBase 认证
大部分的认证都是 FormBase 认证。
- 用户在表单中填写登录信息,发送给服务器。
- 服务器进行验证。
基于表单认证,一般会使用 Cookie 来管理会话(Session)。
HTTP 本身是无状态协议,通过 Cookie 来实现状态管理。
HTTPS 安全通信机制
下图是 HTTPS 的通信步骤。
除标黄部分,其它都是 HTTPS 的安全机制。
- C:开始 SSL 通信
- S:服务器可进行 SSL 通信时的应答
- S:发送公开密钥证书
- S:SSL 第一次握手结束
- C:应答,发送 Pre-master secret 随机密码串(相当于公开密钥)
- C:ChangeCipherSpec 提示服务器,使用 Pre-master secret 随机密码串加密
- C:表示握手结束
- S:ChangeCipherSpec
- S:表示握手结束,SSL 连接建立完成
- C:发送 HTTP 请求(省略了 TCP 连接建立)
- S:发送 HTTP 响应
- C:断开连接
- (省略了 TCP 连接关闭)
为什么不一直使用 HTTPS?
加密通信会消耗更多的 CPU 及内存资源。
如果每次通信都加密,会消耗相当多的资源,能够处理的请求数量会随之减少。
购买证书的开销大。
证书对于 HTTPS 通信来说是必不可少的,而使用证书必须每年向 CA 交授权费用。
因此:非敏感信息使用 HTTP,敏感数据使用 HTTPS。