Files
cs-note/hhs/NETWORK/05-应用层协议/01-HTTP-1-1完全指南.md
T

167 lines
4.6 KiB
Markdown
Raw Normal View History

2026-05-24 11:42:38 +08:00
---
tags: [计算机网络, HTTP, HTTP/1.1, HTTP/2, HTTP/3, QUIC]
create time: 2026-05-18 02:30
---
# HTTP/1.1 完全指南
## 概述
HTTP (HyperText Transfer Protocol) 是万维网的数据传输协议,从 Mosaic 浏览器的最初需求发展而来,至今仍是互联网上使用最广泛的协议之一。
## HTTP 消息结构
```
Request 示例:
POST /api/users HTTP/1.1 ← Request Line
Host: api.example.com ← Headers
Content-Type: application/json ← Header
Content-Length: 42 ← Header
Authorization: Bearer abc123 ← Header
← Blank line separates headers from body
{"name": "Alice", "email": "alice@example.com"} ← Body
Response 示例:
HTTP/1.1 201 Created ← Status Line
Date: Mon, 17 May 2026 02:30:00 GMT ← Headers
Location: https://api.example.com/users/42 ← Header
Content-Type: application/json ← Header
Content-Length: 35 ← Header
{"id": 42, "name": "Alice"} ← Body
```
### Request Line 格式
```
METHOD SP Request-URI SP HTTP-Version CRLF
```
### 常用 Method
| Method | 安全(Safe)? | 幂等(Idempotent)? | 含义 |
|--------|-----------|------------------|------|
| GET | ✅ | ✅ | 获取资源 |
| HEAD | ✅ | ✅ | 只获取响应头 |
| POST | ❌ | ❌ | 提交数据创建新资源 |
| PUT | ❌ | ✅ | 替换整个资源 |
| PATCH | ❌ | ❌ | 部分更新资源 |
| DELETE | ❌ | ✅ | 删除资源 |
| OPTIONS | ✅ | ✅ | 查询服务器支持的 Method |
| CONNECT | N/A | N/A | 建立隧道(代理/HTTPS) |
| TRACE | ✅ | ✅ | 回显收到的请求(调试) |
### 常见 Status Code
| 类别 | 含义 | 举例 |
|------|------|------|
| 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, 429 Too Many Requests |
| 5xx | 服务端错误 | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
## Keep-Alive(持久连接)— HTTP/1.1 默认行为
HTTP/1.1 中 `Connection: keep-alive` 是默认的——一个 TCP 连接可承载多个 HTTP 请求/响应:
```
单一 TCP 连接上的多次请求:
TCP Established ✅
Client → Server: GET /page1.html
Server → Client: 200 + HTML
Client → Server: GET /style.css
Server → Client: 200 + CSS
Client → Server: GET /app.js
Server → Client: 200 + JS
Client → Server: Connection: close (或超时自动关闭)
Server → Client: ACK → TCP FIN
```
**好处:** 避免每次请求都进行三次握手 (+TLS 四次握手)。
### Pipeline(管道化)— HTTP/1.1 的未启用功能
理论上可以在同一个连接上**不等待前一个响应就发送下一个请求**:
```
Client 连续发三个请求:
GET /a ← 不等响应
GET /b
GET /c
Server 必须按顺序返回:
200 /a
200 /b
200 /c
```
**为什么几乎没人用?**
- Server 端实现复杂且 Bug 多
- 一旦某个响应阻塞,后续所有响应都被卡住(HoL blocking)
- HTTP/2 的多路复用彻底解决了这个问题
## Chunked Transfer Encoding
当不知道 Content-Length 时(如流式生成内容),使用 chunked 编码:
```
HTTP/1.1 200 OK
Transfer-Encoding: chunked
5\r\n\r\nHello\r\n ← 5 bytes of data: "Hello"
7\r\n\r\n World!\r\n ← 7 bytes: " World!"
0\r\n\r\n ← 终止 chunk
```
```go
// Go net/http 中自动使用 chunked
w.Header().Set("Transfer-Encoding", "chunked")
w.Write([]byte("part 1"))
w.Write([]byte("part 2"))
w.WriteHeader(200) // WriteHeader 必须在 Write 之后才生效 chunked
```
## Go 中的 HTTP 客户端实践
```go
package main
import (
"fmt"
"io"
"net/http"
"time"
)
func main() {
client := &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
resp, err := client.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
}
```
## 关联笔记
- [[hhs/NETWORK/HTTP/2多路复用]] — HTTP/2 如何解决 HTTP/1.1 的问题
- [[hhs/NETWORK/HTTP/3与QUIC]] — 基于 UDP 的下一代 HTTP
- [[hhs/NETWORK/TCP三次握手与四次挥手]] — HTTP 依赖的底层 TCP 连接