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

4.6 KiB
Raw Blame History

tags, create time
tags create time
计算机网络
HTTP
HTTP/1.1
HTTP/2
HTTP/3
QUIC
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 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 客户端实践

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)
}

关联笔记