🌐 HTTP 协议深度解析
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在 TCP 之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。
📚 学习目标
- 深入理解 HTTP 协议的工作原理和特性
- 掌握 HTTP 请求/响应的结构和格式
- 了解 HTTP/1.x 到 HTTP/2 的演进
- 学习 HTTP 在现代 Web 开发中的应用
🔍 HTTP 简介
HTTP 是应用层协议,同其他应用层协议一样,是为了实现某一类具体应用的协议,并由某一运行在用户空间的应用程序来实现其功能。
🏗️ 基本架构
HTTP 是基于 客户端-服务器(B/S)架构 进行通信的:
- 服务器端实现:
httpd
、nginx
、Apache
等 - 客户端实现:
- 浏览器: Firefox、Chrome、Safari、Edge 等
- 命令行工具:
curl
、wget
、httpie
等
- 默认端口: 80(HTTP)/ 443(HTTPS)
🔧 技术细节
HTTP 是基于 TCP 的应用层协议,因此为了能够随时响应客户端的请求,Web 服务器需要监听在 80/TCP 端口上。
⚙️ 工作原理
HTTP 是基于客户端/服务器模式,且面向连接的。典型的 HTTP 事务处理流程:
📋 处理流程
建立连接 🔗
- 客户端与服务器建立 TCP 连接
发送请求 📤
- 客户端向服务器发送 HTTP 请求
处理请求 ⚙️
- 服务器接收并处理请求
- 根据请求返回相应的资源
关闭连接 🔚
- 服务器返回响应后关闭连接
mermaid
graph TB
A[客户端] -->|1. 建立连接| B[服务器]
A -->|2. 发送请求| B
B -->|3. 处理请求| B
B -->|4. 返回响应| A
A -->|5. 关闭连接| B
1
2
3
4
5
6
2
3
4
5
6
🔄 连接特性
HTTP/1.0 - 短连接
- 特点: 每次连接只处理一个请求
- 优势: 减轻服务器负担,提高执行效率
- 劣势: 频繁建立/断开连接,增加延迟
HTTP/1.1 - 持久连接
- 特点: 连接可以重用于多个请求
- 优势: 减少请求延迟,避免重复的 TCP 握手
- 机制: Keep-Alive 机制
🎯 HTTP 核心特性
🔄 无状态协议
HTTP 是一种 无状态协议,即服务器不保留与客户交易时的任何状态。
javascript
// 每个请求都是独立的
fetch('/api/user/profile') // 请求1 - 独立处理
fetch('/api/user/settings') // 请求2 - 独立处理
fetch('/api/user/orders') // 请求3 - 独立处理
1
2
3
4
2
3
4
优势:
- ✅ 减轻服务器记忆负担
- ✅ 保持较快的响应速度
- ✅ 简化服务器设计
解决方案:
- 🍪 Cookie: 在客户端存储状态信息
- 🔑 Session: 在服务端存储状态信息
- 🎫 Token: 无状态的身份认证方式
🧩 面向对象协议
HTTP 允许传送任意类型的数据对象,通过以下方式标识:
- Content-Type: 指定数据类型
- Content-Length: 指定数据长度
- Content-Encoding: 指定压缩方式
http
Content-Type: application/json; charset=utf-8
Content-Length: 1234
Content-Encoding: gzip
1
2
3
2
3
🛠️ HTTP 能控制什么
🗄️ 缓存控制
http
# 服务端控制缓存
Cache-Control: max-age=3600, public
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
# 客户端控制缓存
If-None-Match: "abc123"
If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🔓 跨域资源共享 (CORS)
http
# 服务端设置 CORS 头
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
1
2
3
4
2
3
4
🔐 身份认证
http
# 基础认证
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
# Bearer Token 认证
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# 自定义认证头
X-API-Key: your-api-key-here
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🌉 代理和隧道
http
# 代理相关头部
Via: 1.1 proxy.example.com
X-Forwarded-For: 203.0.113.195
X-Forwarded-Proto: https
X-Real-IP: 203.0.113.195
1
2
3
4
5
2
3
4
5
📝 HTTP 消息结构
📤 HTTP 请求
http
GET /api/users/123 HTTP/1.1 # 请求行
Host: api.example.com # 请求头部
Accept: application/json
Authorization: Bearer token123
User-Agent: Mozilla/5.0 (Windows NT 10.0)
# 空行
{ # 请求体(可选)
"fields": ["name", "email"]
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
📥 HTTP 响应
http
HTTP/1.1 200 OK # 状态行
Content-Type: application/json; charset=utf-8 # 响应头部
Content-Length: 155
Cache-Control: s-maxage=300, public, max-age=0
Date: Thu, 06 Dec 2024 17:37:18 GMT
ETag: "2e77ad1dc6ab0b53a2996dfd4653c1c3"
Server: nginx/1.18.0
# 空行
{ # 响应体
"id": 123,
"name": "张三",
"email": "zhangsan@example.com",
"created_at": "2024-01-01T00:00:00Z"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
📊 消息结构图
🚀 HTTP/2 的改进
HTTP/1.x 存在的性能问题:
❌ HTTP/1.x 的局限性
- 头部冗余: 标头不会被压缩
- 头部重复: 连续请求的标头高度相似但重复传输
- 队头阻塞: 无法多路复用,必须按顺序处理请求
✅ HTTP/2 的解决方案
🔄 二进制分帧
HTTP/2 将 HTTP/1.x 消息分成帧并嵌入到流中:
- 数据帧: 传输实际数据
- 头部帧: 传输头部信息
- 控制帧: 传输控制信息
javascript
// HTTP/1.x - 文本协议
GET /api/users HTTP/1.1
Host: example.com
Accept: application/json
// HTTP/2 - 二进制协议
[HEADERS Frame]
[DATA Frame]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🔀 多路复用
javascript
// 同时发送多个请求,无需等待
Promise.all([
fetch('/api/users'), // Stream 1
fetch('/api/products'), // Stream 2
fetch('/api/orders') // Stream 3
]).then(responses => {
// 并行处理所有响应
});
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
🗜️ 头部压缩 (HPACK)
http
# 第一个请求
:method: GET
:path: /api/users
host: example.com
user-agent: Mozilla/5.0...
# 第二个请求(压缩后)
:method: GET
:path: /api/products
# host 和 user-agent 被压缩引用
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
🚀 服务器推送
javascript
// 服务器主动推送相关资源
// 当请求 index.html 时,服务器可以同时推送 style.css 和 app.js
1
2
2
📈 性能对比
特性 | HTTP/1.1 | HTTP/2 |
---|---|---|
协议格式 | 文本 | 二进制 |
多路复用 | ❌ | ✅ |
头部压缩 | ❌ | ✅ (HPACK) |
服务器推送 | ❌ | ✅ |
流优先级 | ❌ | ✅ |
🔧 HTTP 方法
📋 常用方法
方法 | 用途 | 幂等性 | 安全性 |
---|---|---|---|
GET | 获取资源 | ✅ | ✅ |
POST | 创建资源 | ❌ | ❌ |
PUT | 更新/创建资源 | ✅ | ❌ |
DELETE | 删除资源 | ✅ | ❌ |
PATCH | 部分更新资源 | ❌ | ❌ |
HEAD | 获取资源头部 | ✅ | ✅ |
OPTIONS | 获取服务器能力 | ✅ | ✅ |
💡 使用示例
javascript
// RESTful API 设计
const api = {
// 获取用户列表
getUsers: () => fetch('/api/users', { method: 'GET' }),
// 创建新用户
createUser: (userData) => fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
}),
// 更新用户信息
updateUser: (id, userData) => fetch(`/api/users/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
}),
// 删除用户
deleteUser: (id) => fetch(`/api/users/${id}`, { method: 'DELETE' })
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
📈 状态码
🎯 状态码分类
javascript
// 1xx - 信息性响应
100: "Continue" // 继续请求
101: "Switching Protocols" // 切换协议
// 2xx - 成功响应
200: "OK" // 请求成功
201: "Created" // 资源已创建
204: "No Content" // 无内容返回
// 3xx - 重定向
301: "Moved Permanently" // 永久重定向
302: "Found" // 临时重定向
304: "Not Modified" // 资源未修改
// 4xx - 客户端错误
400: "Bad Request" // 请求错误
401: "Unauthorized" // 未授权
403: "Forbidden" // 禁止访问
404: "Not Found" // 资源不存在
// 5xx - 服务器错误
500: "Internal Server Error" // 服务器内部错误
502: "Bad Gateway" // 网关错误
503: "Service Unavailable" // 服务不可用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
🛡️ HTTP 安全最佳实践
🔐 HTTPS 的重要性
javascript
// ❌ 不安全的HTTP请求
fetch('http://api.example.com/login', {
method: 'POST',
body: JSON.stringify({ username, password })
});
// ✅ 安全的HTTPS请求
fetch('https://api.example.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({ username, password })
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
🛡️ 安全头部
http
# 安全相关的HTTP头部
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'
1
2
3
4
5
6
2
3
4
5
6
🔧 调试和优化
🕵️ 调试工具
- 浏览器开发者工具: Network 面板
- 命令行工具:
curl
,httpie
- 抓包工具: Wireshark, Fiddler
- 在线工具: Postman, Insomnia
⚡ 性能优化
javascript
// 1. 使用适当的缓存策略
fetch('/api/data', {
headers: {
'Cache-Control': 'max-age=3600'
}
});
// 2. 启用压缩
fetch('/api/data', {
headers: {
'Accept-Encoding': 'gzip, deflate, br'
}
});
// 3. 减少请求数量
const batchRequest = {
users: '/api/users',
products: '/api/products',
orders: '/api/orders'
};
fetch('/api/batch', {
method: 'POST',
body: JSON.stringify(batchRequest)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
🌍 HTTP 相关技术生态
📚 相关协议和技术
- HTTPS: HTTP over TLS/SSL
- HTTP/3: 基于 QUIC 的下一代 HTTP
- WebSocket: 全双工通信协议
- Server-Sent Events: 服务器推送事件
- GraphQL: 查询语言和运行时
🔗 相关资源
- MDN HTTP 文档
- RFC 7230-7237 - HTTP/1.1 规范
- RFC 7540 - HTTP/2 规范
- HTTP/3 Draft