Files
cs-note/hhs/NETWORK/05-应用层协议/01-HTTP-1-1完全指南.md
T
2026-05-24 11:42:38 +08:00

167 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 连接