📖 图解 HTTP¶
- Hypertext Transfer Protocol,超文本传输协议
预置知识¶
预置知识:IP、TCP 和 DNS
- IP 协议的作用是把数据包传送给对方,重要的条件是 IP 地址和 MAC 地址。
- ARP 协议:用以解析地址,根据通信方的 IP 地址反查出对应 MAC 地址。不在同一局域网的通信中转需要用到该协议。
- 路由选择:在到达通信目标前的中转过程中,计算机和路由器只能获悉很粗略的传输路线。没有人能够全面掌握互联网中的传输状况。
- TCP 协议的作用是确保数据能够到达对方,提供字节流服务(Byte Stream Service)
- 它采用三次握手(three-way handshaking)策略。
- TCP 标志:
SYN
表示 synchronize,ACK
表示 acknowledgement。 - 发送端首先发送
SYN
,接收端回传SYN/ACK
,发送端再回传ACK
代表握手结束。 - 如果握手的某个阶段异常中断,TCP 会再次以相同顺序发送数据包。
- TCP 标志:
- 它将大块数据分割成报文段管理。
- 它采用三次握手(three-way handshaking)策略。
- DNS 协议提供域名到 IP 地址之间的解析服务,或逆向从 IP 地址反查域名的服务。
- URL 和 URI
- 完整的绝对 URI 格式:
http://user:pass@www.example.jp:90/dir/index.htm?uid=1#ch1
- 依次为:方案名、登录信息、服务器地址、服务器端口号、带层次的文件路径、查询字符串、片段标识符。
- 方案名可以指定协议(http、ftp 等)、数据(data)或脚本程序(javascript)等。不区分大小写。
- 依次为:方案名、登录信息、服务器地址、服务器端口号、带层次的文件路径、查询字符串、片段标识符。
- 完整的绝对 URI 格式:
基础¶
来自:《图解 HTTP》
一些概念:
- 现在讲解的是 HTTP/1.1。
- HTTP 协议用于 客户端和服务器 端之间的通信,通过 请求和响应 的交换达成通信。
- HTTP 是 不保存状态(stateless)的协议,即不保存之前发送过的请求或响应。
- 为了保持状态,引入了 Cookie 技术。
- 使用 方法 下达命令,指定请求的资源按期望产生某种行为。
-
持久连接(HTTP Persistent Connections,HTTP keep-alive 或 HTTP connection reuse)节省通信量。
- HTTP 初始版本中,每次通信就要断开一次 TCP 连接。
- 只要任意一端没有明确提出断开连接,则保持 TCP 状态。
- 管线化:同时并行发送多个请求,不需要一个接一个等待响应。
-
Cookie 技术:在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Set-Cookie
首部字段:从服务器发送,通知客户端保存 Cookie。- 服务器端发现客户端 Cookie 后,查询是哪一个客户端的请求,并对比服务器记录,得到之前的状态信息。
报文¶
来看一个简单的请求报文:
POST /form/entry HTTP/1.1
Host: hackr.jp
Connection: keep-alive
Content-Type: application/x-www-form-unlencoded
Content-Length: 16
name=ueno&age=37
读到这里,你有没有想起 HTML 表单中关于 POST 方法的讲解?
- 请求报文是由请求方法、请求 URI、协议版本、可选的请求首部字段和内容实体构成的。
- 请求 URI:
- 完整的请求 URI。
- 在首部字段
Host
中写明网络域名或 IP 地址,则使用相对的请求 URI。 - 对服务器本身发起请求,用
*
代替请求 URI,如OPTIONS * HTTP/1.1
。
- 请求 URI:
来看一个简单的响应报文:
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
...
- 响应报文由协议版本、状态码、状态码的原因短语、可选的响应首部字段和实体主体构成的。
HTTP 方法¶
- GET:获取资源
- POST:传输实体主体
- PUT:传输文件
- 因为没有验证机制,任何人都可以上传文件,一般网站不使用该方法。
- HEAD:获得报文首部
- 不返回报文主体,用于确认 URI 有效性及资源更新日期时间等。
- DELETE:删除文件
- 一般也不使用
- OPTIONS:询问支持的方法
- TRACE:追踪路径
- 让服务器端将之前的请求通信环回给客户端。
Max-Forwads
首部字段中填入数值,每经过一个服务器端就减 1,当数值减到 0 时停止继续传输,最后接收请求的服务器端返回 200 OK 响应。- 可以查询发出去的请求是怎样被加工修改的。
- 容易引发 XST 攻击,一般也不使用。
- CONNECT:要求用隧道协议连接代理
CONNECT proxy.hackr.jp:8080 HTTP/1.1
- 主要使用 SSL 和 TLS。
进阶¶
来自:《图解 HTTP》
HTTP 报文内的信息¶
- HTTP 报文本身是字符串文本,用
CR(0x0d)+LF(0x0a)
作换行符。 - 报文首部和报文主体由最初出现的空行来划分。
- 报文首部:请求/状态行 + 各种首部字段
- 请求行:请求方法、请求 URI 和 HTTP 版本。
- 状态行:HTTP 版本、状态码和原因短语。
- 4 种首部:通用首部、请求首部、响应首部、实体首部。
- 报文首部:请求/状态行 + 各种首部字段
- 编码:提升传输速率
- 辨析:报文主体和实体主体,通常这两者相等,当使用编码时产生差异
- 报文:HTTP 通信的基本单位,由 8 位字节流组成。
- 实体:请求或响应的有效载荷数据,由实体首部和 实体主体 组成。
- 压缩传输的 内容编码:gzip(GNU zip)、compress(UNIX 系统标准压缩)、deflate(zlib)、identity(不编码)。
- 分割发送的 分块传输编码(Chunked Transfer Coding):将 实体主体 分成多个块,每一块用十六进制标记块大小,实体最后一块使用
0(CR+LF)
标记。
- 辨析:报文主体和实体主体,通常这两者相等,当使用编码时产生差异
- 多部份对象集合(Multipart)方法:发送多种数据
- 首部字段:
Content-Type
- 来源于 MIME。
- 二进制数据以 ASCII 码字符串编码方式指明。
- 发送的一份 报文主体 内可以含有多类型实体。
- 首部字段:
- 范围请求(Range Request):获取部分内容
- 首部字段:
Range
- 状态码:
206 Partial Content
- 若无法响应范围请求,则返回
200 OK
和完整实体内容。 - 对于多重范围请求,会在
Content-Type
标明multipart/byteranges
- 若无法响应范围请求,则返回
- 首部字段:
- 内容协商(Content Negotiation):返回最合适内容
- 三种类型:服务器驱动协商、客户端驱动协商、透明协商。
HTTP 状态码¶
第一位指定了响应类别。常用的有 14 个状态码。
码 | 信息 |
---|---|
1XX | Informational 信息性状态码:接收的请求正在处理 |
2XX | Success 成功状态码:请求正常处理完毕 |
200 OK | |
204 No Content | |
206 Partial Content | |
3XX | Redirection 重定向状态码:需要进行附加操作以完成请求 |
301 Moved Permanently | 永久性重定向。指定资源路径最后忘记添加斜杠会产生该状态码。 |
302 Found | 临时性重定向。希望用户(本次)能使用新 URI 访问,已移动的资源 URI 将来还有可能发生改变。 |
303 See Other | 与 302 功能相同,但明确表示客户端应当采用 GET 方法获取资源。 |
304 Not Modified | 资源已找到,但未符合条件请求。 |
307 Temporary Redirect | 与 302 功能相同,不会从 POST 变成 GET。 |
4XX | Client Error 客户端错误状态码:服务器无法处理请求 |
400 Bad Request | 请求报文中存在语法错误。浏览器当作 200 OK 对待。 |
401 Unauthorized | |
403 Forbidden | 服务器没有必要给出拒绝理由。 |
404 Not Found | 可在拒绝请求且不想说明理由时使用。 |
5XX | Server Error 服务器错误状态码:服务器处理请求出错 |
500 Internal Server Error | |
503 Service Unavailable |
- 不少返回的状态码响应都是错误的,但用户可能察觉不到这点。Web 应用程序内发生错误也依然返回 200 OK。
Web 服务器¶
回忆一下你对 Nginx、Apache 等服务器的认识。
- 一台虚拟主机实现多个域名
- 经过 DNS 解析后,请求发送到服务器时,已经是 IP 地址的形式了。如果一台服务器内托管多个域名,就需要弄清楚请求要访问哪个域名。
- 因此,必须在
Host
首部内完整指定主机名或域名 URI。
- 通信数据转发程序:代理、网关、隧道
- 代理:位于服务器和客户端中间,只负责转发。
- 每次通过代理服务器时会追加
Via
首部。 - 功能:利用缓存减少网络流量、针对特定网站的访问控制等。
- 分类:缓存代理和透明代理。
- 每次通过代理服务器时会追加
- 网关:转发其他服务器通信数据的服务器。接收请求时,就像源服务器一样对请求进行处理。用户可能不会察觉自己的通信目标是一个网关。
- 和代理类似,但允许服务器使用非 HTTP 协议。
- 能在客户端与网关之间的通信线路加密提高通信的安全性。
- 隧道:在相隔很远的客户端和服务器之间进行中转,保持双方通信连接。
- 确保安全的通信。
- 隧道本身不会解析 HTTP 请求。
- 会在通信双方断开连接时结束。
- 隧道本身透明,客户端无需在意隧道的存在。
- 代理:位于服务器和客户端中间,只负责转发。
- 缓存
HTTP 首部¶
- 首部字段(Header Fields)结构:
首部字段名:字段值
,可以有多个字段值。
首部字段重复
规范尚未明确,根据浏览器内部处理逻辑不同,结果可能不一致。
HTTP 首部字段分为 4 种类型:
- 通用首部字段:双方都会使用的首部
字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
- 请求首部字段:请求报文使用的首部
字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Authorization | Web 认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Math | 比较实体标记 |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节流范围请求 |
Referer | 对请求中 URI 的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP 客户端程序的信息 |
- 响应首部字段
字段名 | 说明 |
---|---|
Accept |