HTTP
→ 返回 计算机网络
HTTP(HyperText Transfer Protocol)是 Web 的基础传输协议,运行在 TCP 之上,无状态、明文传输。
请求与响应结构
请求
GET /api/users?page=1 HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer <token>
| 部分 | 说明 |
|---|---|
| 请求行 | 方法 + 路径 + 协议版本 |
| 请求头 | 键值对元数据 |
| 空行 | 头和体的分隔符 |
| 请求体 | POST/PUT 时携带数据 |
响应
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 42
{"id": 1, "name": "Alice"}
常用方法
| 方法 | 语义 | 幂等 | 有请求体 |
|---|---|---|---|
| GET | 获取资源 | 是 | 否 |
| POST | 创建资源 | 否 | 是 |
| PUT | 全量更新 | 是 | 是 |
| PATCH | 部分更新 | 否 | 是 |
| DELETE | 删除资源 | 是 | 否 |
| HEAD | 同 GET,只返回头部 | 是 | 否 |
| OPTIONS | 查询支持的方法(CORS 预检) | 是 | 否 |
状态码
| 分类 | 含义 | 常见状态码 |
|---|---|---|
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 重定向 | 301 永久重定向、302 临时重定向、304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、429 Too Many Requests |
| 5xx | 服务端错误 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable |
HTTP 版本演进
| 版本 | 关键特性 |
|---|---|
| HTTP/1.0 | 短连接,每次请求建立新 TCP |
| HTTP/1.1 | 持久连接(keep-alive),管道化(有队头阻塞) |
| HTTP/2 | 二进制帧、多路复用、头部压缩(HPACK)、服务端推送 |
| HTTP/3 | 基于 QUIC(UDP),彻底解决队头阻塞,0-RTT 连接 |
HTTP/2 多路复用
TCP 连接
├── 流 1(请求 A)
├── 流 2(请求 B)
└── 流 3(请求 C)
多个请求并发,互不阻塞
Cookie 与 Session
| 机制 | 存储位置 | 说明 |
|---|---|---|
| Cookie | 客户端浏览器 | 由服务端 Set-Cookie 设置,每次请求自动携带 |
| Session | 服务端内存 / 数据库 | 服务端维护状态,客户端只持有 SessionID |
| JWT | 客户端(Cookie 或 Header) | 无状态 Token,服务端不存储 |
缓存
| 头部 | 说明 |
|---|---|
Cache-Control: max-age=3600 | 强缓存,3600 秒内不请求服务器 |
Cache-Control: no-cache | 每次需向服务器验证(协商缓存) |
ETag | 资源指纹,配合 If-None-Match 使用 |
Last-Modified | 资源最后修改时间,配合 If-Modified-Since |
命中强缓存返回 200(from cache);协商缓存未变更返回 304。
CORS(跨域资源共享)
浏览器同源策略阻止跨域请求,服务端通过响应头授权:
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Authorization, Content-Type
复杂请求(非 GET/POST 或带自定义头)会先发 OPTIONS 预检请求。
Content-Type 常见类型
| 类型 | 说明 | 使用场景 |
|---|---|---|
application/json | JSON 数据 | REST API 请求/响应体 |
application/x-www-form-urlencoded | 表单编码(键=值&键=值) | HTML 表单默认提交 |
multipart/form-data | 多部分表单,支持文件 | 上传文件 |
text/html | HTML 文档 | 页面响应 |
text/plain | 纯文本 | 日志、简单文本 |
application/octet-stream | 二进制流 | 文件下载 |
重定向细节
301、302、307、308 均为重定向,但行为不同:
| 状态码 | 永久/临时 | 方法保持 | 说明 |
|---|---|---|---|
| 301 | 永久 | 否(POST→GET) | SEO 权重转移,浏览器缓存目标 URL |
| 302 | 临时 | 否(POST→GET) | 临时跳转,常被错误用于 POST |
| 307 | 临时 | 是 | 保留原方法,登录后重定向到原 POST |
| 308 | 永久 | 是 | 301 的严格版本 |
内容压缩
服务端对响应体压缩,减少传输体积:
请求头:
Accept-Encoding: gzip, br, deflate
响应头:
Content-Encoding: gzip
| 算法 | 压缩率 | 速度 | 说明 |
|---|---|---|---|
| gzip | 中 | 快 | 兼容性最好,通用首选 |
| br(Brotli) | 高(比 gzip 好 20-30%) | 稍慢 | 现代浏览器支持,HTTPS 下推荐 |
| deflate | 低 | 快 | 已基本淘汰 |
断点续传(Range 请求)
适用于大文件下载恢复、视频拖动:
请求头:
Range: bytes=0-1023 # 请求第 0~1023 字节
响应(206 Partial Content):
Content-Range: bytes 0-1023/10240
Content-Length: 1024
服务端返回 Accept-Ranges: bytes 表示支持范围请求。
安全响应头
| 头部 | 作用 |
|---|---|
Content-Security-Policy | 限制资源来源,防止 XSS |
X-Frame-Options: DENY | 禁止页面被嵌入 iframe,防止点击劫持 |
X-Content-Type-Options: nosniff | 禁止 MIME 嗅探 |
Strict-Transport-Security | 强制 HTTPS(HSTS) |
Referrer-Policy | 控制 Referer 头发送策略 |
RESTful 设计原则
REST 是一套基于 HTTP 的 API 设计风格,而非协议:
# 资源以名词表示,复数形式
GET /api/users # 列表
GET /api/users/42 # 单个资源
POST /api/users # 创建
PUT /api/users/42 # 全量更新
PATCH /api/users/42 # 部分更新
DELETE /api/users/42 # 删除
# 嵌套资源
GET /api/users/42/orders # 用户的订单列表
POST /api/users/42/orders # 创建订单
常见约定:
- 用 HTTP 方法表示动作,URL 只表示资源
- 状态码语义化(不要全用 200 + 自定义 code)
- 分页:
?page=1&size=20或游标分页?cursor=xxx - 版本:
/api/v1/...或请求头API-Version: 2
HTTP 长轮询
在 WebSocket 出现前,实现服务端推送的折中方案:
客户端发请求 → 服务端 hold 住不响应 → 有新数据时返回
客户端收到响应后立即再发下一个请求
| 方式 | 原理 | 延迟 | 开销 |
|---|---|---|---|
| 短轮询 | 固定间隔发请求 | 高(受间隔限制) | 大量无效请求 |
| 长轮询 | hold 住请求直到有数据 | 低 | 连接占用大 |
| SSE | HTTP 流式响应,服务端推送 | 低 | 单向,不需要 WS 协议 |
| WebSocket | 全双工持久连接 | 最低 | 最佳双向实时通信 |