--- 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 连接