目录

HTTP 协议:从基础到高级通信模式

HTTP(HyperText Transfer Protocol)是 Web 的基础协议,浏览器与服务器之间的每一次交互都依赖它。本文从基础模型出发,逐步覆盖状态管理、安全加密、协议演进,以及 SSE 和 WebSocket 等高级通信模式。

HTTP 基础

通信模型

HTTP 采用客户端-服务器(C/S)模型,通信过程是一问一答

  1. 客户端(浏览器)发起请求(Request)
  2. 服务器处理后返回响应(Response)
  3. 连接断开(HTTP/1.1 默认 keep-alive 可复用连接)

HTTP 是无状态协议——服务器不会记住之前的请求。每次请求都是独立的,服务器不知道"这个用户是谁"。

请求结构

一个 HTTP 请求由三部分组成:

GET /api/users?page=1 HTTP/1.1        ← 请求行(方法 + 路径 + 版本)
Host: example.com                       ← 请求头
Accept: application/json
Authorization: Bearer xxx

                                        ← 空行
                                        ← 请求体(GET 通常无 body)

响应结构

HTTP/1.1 200 OK                         ← 状态行(版本 + 状态码 + 原因短语)
Content-Type: application/json          ← 响应头
Content-Length: 42

{"users": ["alice", "bob"]}             ← 响应体

HTTP 方法

方法 语义 幂等 有请求体 典型场景
GET 获取资源 查询数据
POST 创建资源 提交表单、创建记录
PUT 替换资源 更新整个资源
PATCH 部分更新 修改部分字段
DELETE 删除资源 删除记录
HEAD 只获取头 检查资源是否存在
OPTIONS 查询支持的方法 CORS 预检请求

幂等意味着同一个请求执行多次,效果与执行一次相同。GETPUTDELETE 是幂等的,POST 不是——重复提交 POST /orders 会创建多个订单。

状态码

范围 类别 常见状态码
1xx 信息 100 Continue101 Switching Protocols
2xx 成功 200 OK201 Created204 No Content
3xx 重定向 301 Moved Permanently302 Found304 Not Modified
4xx 客户端错误 400 Bad Request401 Unauthorized403 Forbidden404 Not Found429 Too Many Requests
5xx 服务器错误 500 Internal Server Error502 Bad Gateway503 Service Unavailable

容易混淆的状态码

  • 401 vs 403:401 是"未认证"(没有登录),403 是"已认证但无权限"
  • 301 vs 302:301 是永久重定向(浏览器会缓存),302 是临时重定向
  • 404 vs 410:404 是"找不到",410 是"曾经有但已永久删除"

请求头与响应头

常用请求头

头字段 作用 示例
Host 目标主机(HTTP/1.1 必须) Host: api.example.com
Authorization 认证凭证 Bearer eyJhbG...
Content-Type 请求体格式 application/json
Accept 期望的响应格式 application/json
Cache-Control 缓存策略 no-cachemax-age=3600
If-None-Match 条件请求(配合 ETag) "abc123"
Cookie 客户端存储的 Cookie session_id=xyz
User-Agent 客户端标识 Mozilla/5.0 ...

常用响应头

头字段 作用 示例
Content-Type 响应体格式 text/html; charset=utf-8
Cache-Control 缓存控制 public, max-age=86400
ETag 资源版本标识 "a1b2c3"
Set-Cookie 设置 Cookie session=abc; HttpOnly
Access-Control-* CORS 跨域控制 Access-Control-Allow-Origin: *
Location 重定向目标 /new-page

状态管理:Cookie 与 Session

HTTP 无状态,但实际应用需要记住用户(登录状态、购物车等)。解决方案有两种:

服务器通过 Set-Cookie 响应头在客户端存储数据,浏览器后续请求会自动带上 Cookie 头。

# 服务器响应
Set-Cookie: session_id=abc123; HttpOnly; Secure; Max-Age=3600

# 浏览器后续请求自动携带
Cookie: session_id=abc123

Cookie 属性

属性 作用
HttpOnly 禁止 JavaScript 访问(防 XSS)
Secure 仅通过 HTTPS 传输
SameSite 限制跨站发送(Strict/Lax/None
Max-Age 过期时间(秒)
Path Cookie 生效的路径范围

Session

Session 将状态存储在服务器端,客户端只保留一个 Session ID(通过 Cookie 传递)。

客户端 Cookie:  session_id=abc123
服务器内存/Redis: { "abc123": { "user": "alice", "role": "admin" } }

Cookie vs Session

对比 Cookie Session
存储位置 客户端 服务器
安全性 较低(可被篡改) 较高
容量限制 ~4KB/个 取决于服务器内存
服务器压力 需要存储空间

JWT(现代方案)

JWT(JSON Web Token)将用户信息直接编码在 Token 中,服务器无需存储 Session:

# JWT 结构
Header.Payload.Signature

# 请求时放在 Authorization 头
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWxpY2UifQ.xxx

HTTPS 与 TLS

HTTPS = HTTP + TLS(Transport Layer Security),在 HTTP 基础上加密传输数据。

TLS 握手过程

Client                              Server
  │── ClientHello (支持的加密套件) ──→│
  │←── ServerHello (选定的加密套件) ──│
  │←── 服务器证书 ──────────────────│
  │←── ServerHelloDone ─────────────│
  │── 客户端密钥交换 ──────────────→│
  │── ChangeCipherSpec ────────────→│
  │── Finished ────────────────────→│
  │←── ChangeCipherSpec ────────────│
  │←── Finished ────────────────────│
  │                                  │
  │←══ 加密通信 ═══════════════════→│

关键概念

  • 对称加密:用同一个密钥加密和解密(AES),速度快,用于数据传输
  • 非对称加密:公钥加密、私钥解密(RSA/ECC),用于密钥交换
  • 证书:由 CA(证书颁发机构)签发,证明服务器身份

HTTP 协议演进

HTTP/1.1

  • 持久连接:默认 Connection: keep-alive,复用 TCP 连接
  • 管道化:允许连续发送多个请求,但响应必须按序返回(队头阻塞)
  • 缺点:每个域名限制 6-8 个并发连接,队头阻塞严重

HTTP/2

HTTP/2 解决了 HTTP/1.1 的性能瓶颈:

特性 说明
多路复用 一个 TCP 连接上并行传输多个请求/响应,无队头阻塞
头部压缩 HPACK 算法压缩重复的 Header,减少传输量
服务器推送 服务器可主动推送客户端可能需要的资源(CSS/JS)
二进制分帧 将数据拆分为二进制帧传输,解析更高效
HTTP/1.1:  请求1 → 响应1 → 请求2 → 响应2(串行)
HTTP/2:    请求1 ↘
           请求2 →→ 同一个连接并行传输 →→ 响应1
           请求3 ↗                          响应2
                                            响应3

HTTP/3

HTTP/3 用 QUIC(基于 UDP)替代 TCP:

  • 解决 TCP 队头阻塞:丢包只影响对应的流,不影响其他流
  • 更快的连接建立:0-RTT 或 1-RTT 握手(TCP + TLS 需要 2-3 RTT)
  • 连接迁移:网络切换(Wi-Fi → 4G)时连接不断开

高级通信模式

标准 HTTP 是"请求-响应"模式,但现代应用需要更灵活的通信方式。

SSE(Server-Sent Events)

SSE 是基于 HTTP 的服务器单向推送技术。客户端发起一次 HTTP 请求后,服务器通过流式响应持续推送数据。

客户端 ──GET /events──→ 服务器
客户端 ←── data: {...} ── 服务器(持续推送)
客户端 ←── data: {...} ── 服务器
客户端 ←── data: {...} ── 服务器

特点

  • 基于标准 HTTP,无需特殊协议
  • 自动重连(浏览器内置 EventSource API)
  • 文本格式(text/event-stream

适用场景:AI 流式输出、实时通知、股票行情、日志推送

// 客户端
const es = new EventSource('/api/stream');
es.onmessage = (e) => console.log(e.data);

详细实现参见 SSE 实战文章

WebSocket

WebSocket 是全双工通信协议,客户端和服务器可以随时互发消息。

握手过程:通过 HTTP 升级协议

客户端 ──GET /chat (Upgrade: websocket)──→ 服务器
客户端 ←── 101 Switching Protocols ──────── 服务器
客户端 ←══════ 双向数据帧通信 ═══════→ 服务器

特点

  • 全双工:双方可随时发送消息
  • 二进制和文本都支持
  • 需要专门的 WebSocket 服务器

适用场景:在线聊天、多人协作编辑、实时游戏、协同白板

// 客户端
const ws = new WebSocket('wss://example.com/chat');
ws.onmessage = (e) => console.log(e.data);
ws.send('Hello');

SSE vs WebSocket 对比

对比维度 SSE WebSocket
通信方向 服务器 → 客户端(单向) 双向
协议 HTTP 独立协议(ws://)
自动重连 内置 需手动实现
数据格式 文本 文本 + 二进制
防火墙/代理 友好(标准 HTTP) 可能被拦截
适用场景 通知、推送、流式输出 聊天、游戏、协作

选择建议

  • 只需要服务器推送 → SSE(更简单、更可靠)
  • 需要双向实时通信 → WebSocket
  • AI 应用流式输出 → SSE(兼容性好,实现简单)

长轮询(Long Polling)

在 SSE 和 WebSocket 普及之前的折中方案:

客户端 ──GET /poll──→ 服务器(挂起连接,直到有新数据)
客户端 ←── 响应 ──── 服务器
客户端 ──GET /poll──→ 服务器(立即发起下一次)

缺点:每次响应后需要重新建立连接,延迟较高,服务器压力大。现代应用应优先选择 SSE 或 WebSocket。

相关协议对比

HTTP 是应用层协议,以下协议同属应用层,各有分工:

协议 用途 端口 特点
HTTP/HTTPS Web 数据传输 80/443 无状态、请求-响应
DNS 域名解析 53 将域名转换为 IP 地址
SSH 安全远程登录 22 加密替代 Telnet,详见 SSH 指南
FTP 文件传输 20/21 明文传输,不安全
SMTP 发送邮件 25/587 发件服务器之间通信
POP3/IMAP 接收邮件 110/143 POP3 下载删除,IMAP 同步保留
WebSocket 实时双向通信 80/443 基于 HTTP 升级

DNS 解析流程

DNS 是所有网络通信的起点——浏览器必须先通过 DNS 将域名解析为 IP 地址:

浏览器缓存 → 系统 hosts 文件 → 本地 DNS 服务器 → 根 DNS → 顶级域 DNS → 权威 DNS
                                                            返回 IP 地址

总结

需求 方案
获取/提交数据 HTTP GET/POST
保持登录状态 Cookie + Session / JWT
加密传输 HTTPS (TLS)
高性能并发 HTTP/2 多路复用
服务器推送 SSE
双向实时通信 WebSocket
下一代协议 HTTP/3 (QUIC)