HTTP 报文结构与状态码
HTTP 请求/响应报文的组成部分及常见状态码含义
问题
描述 HTTP 报文的结构,并解释常见状态码(200, 301, 302, 304, 400, 401, 403, 404, 500, 502)的含义。
解答
HTTP 报文结构
HTTP 报文分为请求报文和响应报文,都由三部分组成:
┌─────────────────────────────┐
│ 起始行(请求行/响应行) │
├─────────────────────────────┤
│ 头部(Headers) │
├─────────────────────────────┤
│ 空行 │
├─────────────────────────────┤
│ 实体(Body) │
└─────────────────────────────┘
请求报文
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer token123
Content-Length: 27
{"name":"John","age":25}
请求行:方法 + 路径 + HTTP版本
POST /api/users HTTP/1.1
响应报文
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 45
Cache-Control: max-age=3600
{"id":1,"name":"John","age":25}
响应行:HTTP版本 + 状态码 + 状态描述
HTTP/1.1 200 OK
常见请求头
| 头部 | 说明 |
|---|---|
Host | 目标主机 |
Content-Type | 请求体类型 |
Authorization | 认证信息 |
Cookie | 客户端 Cookie |
User-Agent | 客户端标识 |
Accept | 可接受的响应类型 |
常见响应头
| 头部 | 说明 |
|---|---|
Content-Type | 响应体类型 |
Content-Length | 响应体长度 |
Set-Cookie | 设置 Cookie |
Cache-Control | 缓存策略 |
Location | 重定向地址 |
常见状态码
2xx 成功
| 状态码 | 含义 |
|---|---|
| 200 OK | 请求成功 |
3xx 重定向
| 状态码 | 含义 |
|---|---|
| 301 Moved Permanently | 永久重定向,资源已永久移动到新 URL |
| 302 Found | 临时重定向,资源临时移动 |
| 304 Not Modified | 资源未修改,使用缓存 |
// 301 vs 302 的区别
// 301: 浏览器会缓存重定向,下次直接访问新地址
// 302: 每次都会先请求原地址
// 304 场景:协商缓存命中
// 请求头带 If-Modified-Since 或 If-None-Match
// 服务器验证资源未变化,返回 304
4xx 客户端错误
| 状态码 | 含义 |
|---|---|
| 400 Bad Request | 请求语法错误,服务器无法理解 |
| 401 Unauthorized | 未认证,需要登录 |
| 403 Forbidden | 已认证但无权限访问 |
| 404 Not Found | 资源不存在 |
// 401 vs 403 的区别
// 401: 你是谁?(未登录)
// 403: 我知道你是谁,但你没权限(已登录但权限不足)
5xx 服务器错误
| 状态码 | 含义 |
|---|---|
| 500 Internal Server Error | 服务器内部错误 |
| 502 Bad Gateway | 网关/代理收到上游服务器的无效响应 |
// 500 vs 502 的区别
// 500: 服务器自身代码出错
// 502: 服务器作为网关,上游服务器挂了或返回异常
使用 fetch 处理不同状态码
async function request(url) {
const response = await fetch(url);
switch (response.status) {
case 200:
return response.json();
case 301:
case 302:
// fetch 会自动跟随重定向
console.log('重定向到:', response.url);
return response.json();
case 304:
// 使用缓存数据
return getCachedData(url);
case 400:
throw new Error('请求参数错误');
case 401:
// 跳转登录
redirectToLogin();
break;
case 403:
throw new Error('没有访问权限');
case 404:
throw new Error('资源不存在');
case 500:
throw new Error('服务器错误');
case 502:
throw new Error('网关错误,请稍后重试');
default:
throw new Error(`未知错误: ${response.status}`);
}
}
关键点
- HTTP 报文由三部分组成:起始行、头部、实体,头部和实体之间有空行分隔
- 301 是永久重定向(浏览器缓存),302 是临时重定向(每次请求原地址)
- 304 表示协商缓存命中,服务器告诉客户端使用本地缓存
- 401 是未认证(需登录),403 是无权限(已登录但权限不足)
- 500 是服务器自身错误,502 是网关收到上游无效响应
目录