HTTP 协议深度解析(二):方法、状态码与 Header 详解
HTTP 协议包含多种请求方法、状态码及响应头字段。 GET、POST、PUT、DELETE 等方法的区别与应用场景,分析 2xx 至 5xx 各类状态码含义及重定向原理。同时梳理 Content-Type、Host、User-Agent 等常见 Header 的作用,涵盖表单提交、文件上传及缓存控制机制,帮助开发者深入理解网络通信核心逻辑。

HTTP 协议包含多种请求方法、状态码及响应头字段。 GET、POST、PUT、DELETE 等方法的区别与应用场景,分析 2xx 至 5xx 各类状态码含义及重定向原理。同时梳理 Content-Type、Host、User-Agent 等常见 Header 的作用,涵盖表单提交、文件上传及缓存控制机制,帮助开发者深入理解网络通信核心逻辑。

HTTP 方法(Method)也叫 HTTP 动词(Verb),用于告诉服务器客户端想要执行什么操作。
常见方法:
| 方法 | 含义 | 常用程度 |
|---|---|---|
| GET | 获取资源 | ⭐⭐⭐⭐⭐ |
| POST | 提交数据 | ⭐⭐⭐⭐⭐ |
| HEAD | 获取响应头 | ⭐⭐ |
| PUT | 更新资源 | ⭐⭐ |
| DELETE | 删除资源 | ⭐⭐ |
| OPTIONS | 查询支持的方法 | ⭐ |
| TRACE | 回显请求 | ⭐ |
| CONNECT | 建立隧道 | ⭐ |
最常用的是GET 和 POST,占据了 99% 以上的 HTTP 请求。
用途:请求获取指定资源。
请求格式:
GET /index.html HTTP/1.1
Host: www.example.com
特点:
示例:
GET /search?keyword=Linux&page=2 HTTP/1.1
Host: www.example.com
服务器解析出:
示例 URL:
http://www.baidu.com/s?wd=Linux # 百度搜索
http://www.example.com/api/users?id=123 # API 查询
http://www.example.com/images/logo.png # 加载图片
用途:向服务器提交数据。
请求格式:
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
username=admin&password=123
特点:
示例:
POST /api/register HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
username=zhangsan&password=123456&[email protected]
| 对比项 | GET | POST |
|---|---|---|
| 参数位置 | URL 查询字符串 | Body 中 |
| 参数长度 | 有限制(2KB-8KB) | 理论无限制 |
| 安全性 | 参数暴露在 URL | 相对安全 |
| 缓存 | 会被缓存 | 一般不会被缓存 |
| 书签 | 可以收藏 | 不能收藏 |
| 后退/刷新 | 无影响 | 数据会重新提交 |
| 语义 | 获取资源 | 提交数据 |
| 幂等性 | 幂等(多次请求结果相同) | 非幂等 |
幂等性的例子:
GET /api/users?id=123 # 多次请求,返回同样的用户信息(幂等)
POST /api/orders # 多次请求,会创建多个订单(非幂等)
重要误区:
用途:获取响应头,不返回 Body。
请求格式:
HEAD /index.html HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Last-Modified: Wed, 21 Oct 2023 07:20:00 GMT
# (没有 Body)
curl 测试:
# HEAD 请求
curl --head http://www.baidu.com
# 输出(只有响应头,没有 Body)
HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Wed, 21 Oct 2023 07:28:00 GMT
Content-Type: text/html
Content-Length: 2381
...
用途:更新资源。
请求格式:
PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 45
{"name":"张三","age":30,"city":"北京"}
特点:
PUT vs POST:
POST:向集合资源创建子资源(服务器分配 URI)
PUT:对指定 URI 的资源整体替换/创建(客户端知道 URI)
用途:删除资源。
请求格式:
DELETE /api/users/123 HTTP/1.1
Host: www.example.com
特点:
用途:查询服务器支持哪些 HTTP 方法。
请求格式:
OPTIONS /api/users HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
Content-Length: 0
应用场景:
curl 测试:
curl -X OPTIONS http://127.0.0.1/
# 如果服务器不支持 OPTIONS
HTTP/1.1 405 Not Allowed
Content-Type: text/html
Content-Length: 166
<html><head><title>405 Not Allowed</title></head><body><center><h1>405 Not Allowed</h1></center></body></html>
HTML 表单(Form)是网页中收集用户输入的主要方式。
基本结构:
<form action="/api/login" method="POST">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
关键属性:
action:表单提交的 URLmethod:HTTP 方法(GET 或 POST)<form action="/search" method="GET">
<input type="text" name="keyword" placeholder="搜索关键词">
<input type="number" name="page" value="1">
<button type="submit">搜索</button>
</form>
用户输入"Linux",点击提交,浏览器发送:
GET /search?keyword=Linux&page=1 HTTP/1.1
Host: www.example.com
特点:参数拼接到 URL 后面。
<form action="/api/login" method="POST">
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<button type="submit">登录</button>
</form>
用户输入用户名"admin",密码"123",点击提交,浏览器发送:
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
username=admin&password=123
特点:参数在 Body 中,格式是 key1=value1&key2=value2。
POST 表单的 Content-Type 有多种:
格式:键值对,&分隔,和 URL 查询参数相同。
Content-Type: application/x-www-form-urlencoded
username=admin&password=123&email=test%40qq.com
特殊字符需要 urlencode(如@变成%40)。
用途:上传文件。
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="avatar">
<button type="submit">上传</button>
</form>
请求:
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data;boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 234
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data;name="avatar";filename="photo.jpg"
Content-Type: image/jpeg
(二进制图片数据)
------WebKitFormBoundary7MA4YWxkTrZu0gW--
boundary是分隔符,每个字段用 boundary 分隔。
用途:提交 JSON 数据(现代 Web API 常用)。
fetch('/api/login',{
method:'POST',
headers:{'Content-Type':'application/json'},
body:JSON.stringify({username:'admin',password:'123'})
});
请求:
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 45
{"username":"admin","password":"123"}
HTTP 状态码是三位数字,表示请求的处理结果。
| 分类 | 范围 | 含义 |
|---|---|---|
| 1xx | 100-199 | 信息性状态码(请求正在处理) |
| 2xx | 200-299 | 成功状态码(请求成功) |
| 3xx | 300-399 | 重定向状态码(需要进一步操作) |
| 4xx | 400-499 | 客户端错误状态码 |
| 5xx | 500-599 | 服务器错误状态码 |
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 100 Continue | 继续 | 上传大文件时,服务器告诉客户端可以继续上传 |
100 Continue 的使用:
客户端先发送请求头:
POST /upload HTTP/1.1
Host: www.example.com
Content-Length: 104857600
Expect: 100-continue
服务器返回:
HTTP/1.1 100 Continue
客户端继续发送 Body(100MB 的文件数据)
避免客户端发送大量数据后才发现服务器不接受请求。
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 200 OK | 成功 | 访问网页、API 查询成功 |
| 201 Created | 已创建 | POST 创建资源成功 |
| 204 No Content | 无内容 | DELETE 成功,不返回内容 |
最常见的状态码,表示请求成功。
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
<html>...</html>
表示资源创建成功。
POST /api/articles HTTP/1.1
Content-Type: application/json
{"title":"新文章","content":"内容"}
响应:
HTTP/1.1 201 Created
Location: /api/articles/123
Content-Type: application/json
{"id":123,"title":"新文章","content":"内容"}
Location 字段指示新资源的 URL。
表示成功,但没有返回内容。
DELETE /api/articles/123 HTTP/1.1
响应:
HTTP/1.1 204 No Content
Content-Length: 0
| 状态码 | 含义 | 是否永久 | 应用场景 |
|---|---|---|---|
| 301 Moved Permanently | 永久重定向 | 是 | 网站换域名 |
| 302 Found | 临时重定向 | 否 | 登录后跳转 |
| 304 Not Modified | 未修改 | - | 浏览器缓存 |
| 307 Temporary Redirect | 临时重定向 | 否 | 保持 HTTP 方法 |
| 308 Permanent Redirect | 永久重定向 | 是 | 保持 HTTP 方法 |
表示资源已永久移动到新位置。
GET /old-page HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 301 Moved Permanently
Location: http://www.example.com/new-page
Content-Length: 0
浏览器行为:
应用场景:
http://old.com → http://new.comhttp://example.com → https://example.com表示资源临时移动到新位置。
GET /login HTTP/1.1
Host: www.example.com
响应:
HTTP/1.1 302 Found
Location: http://www.example.com/dashboard
Content-Length: 0
浏览器行为:
应用场景:
301:通常被当作永久迁移,搜索引擎更倾向转移权重
302:通常被当作临时迁移,搜索引擎更倾向保留原地址(但会根据长期行为调整)
表示资源未修改,使用缓存版本。
GET /style.css HTTP/1.1
Host: www.example.com
If-Modified-Since: Wed, 21 Oct 2023 07:20:00 GMT
响应:
HTTP/1.1 304 Not Modified
Last-Modified: Wed, 21 Oct 2023 07:20:00 GMT
Content-Length: 0
浏览器行为:
优势:节省带宽,提高性能。
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 400 Bad Request | 请求错误 | 参数格式错误 |
| 401 Unauthorized | 未认证 | 未登录或 token 过期 |
| 403 Forbidden | 禁止访问 | 没有权限 |
| 404 Not Found | 未找到 | 资源不存在 |
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: ...
{invalid json}
需要认证(登录)。
GET /api/profile HTTP/1.1
响应:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
{"error":"Authentication required"}
没有权限访问。
GET /admin/users HTTP/1.1
Authorization: Bearer <user_token>
响应:
HTTP/1.1 403 Forbidden
{"error":"Admin access required"}
401 vs 403:
资源不存在。
GET /nonexistent-page HTTP/1.1
响应:
HTTP/1.1 404 Not Found
Content-Type: text/html
<html><body><h1>404 Not Found</h1></body></html>
| 状态码 | 含义 | 应用场景 |
|---|---|---|
| 500 Internal Server Error | 服务器内部错误 | 代码异常、崩溃 |
| 502 Bad Gateway | 网关错误 | 代理服务器无法连接上游服务器 |
| 503 Service Unavailable | 服务不可用 | 服务器维护或过载 |
| 504 Gateway Timeout | 网关超时 | 上游服务器响应超时 |
服务器内部错误(代码 bug、数据库错误等)。
GET /api/users HTTP/1.1
响应:
HTTP/1.1 500 Internal Server Error
Content-Type: text/html
<html><body><h1>500 Internal Server Error</h1></body></html>
代理服务器无法从上游服务器获取有效响应。
架构:浏览器 → Nginx(代理) → 应用服务器
如果应用服务器挂了,Nginx 返回:
HTTP/1.1 502 Bad Gateway
服务暂时不可用(维护、过载等)。
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: text/plain
Content-Length: 19
Service Unavailable
Location 字段指定重定向的目标 URL。
可以是相对路径或绝对路径:
# 相对路径
Location: /new-page
# 绝对路径
Location: http://www.example.com/new-page
# 不同域名
Location: http://www.newdomain.com/page
| 对比项 | 301 | 302 |
|---|---|---|
| 含义 | 永久重定向 | 临时重定向 |
| 搜索引擎 | 更新索引,权重转移 | 保留原 URL 索引 |
| 浏览器缓存 | 可能缓存重定向 | 不缓存 |
| 应用场景 | 网站换域名、HTTP→HTTPS | 登录跳转、临时维护页面 |
例子:
网站换域名(用 301):
访问 http://old.com
返回:
HTTP/1.1 301 Moved Permanently
Location: http://new.com
浏览器自动跳转到 http://new.com
搜索引擎更新索引,old.com 的权重转移到 new.com
登录跳转(用 302):
访问 http://example.com/dashboard(需要登录)
返回:
HTTP/1.1 302 Found
Location: http://example.com/login
浏览器自动跳转到登录页
登录成功后,再跳转回 dashboard
修改我们的 HTTP 服务器,添加重定向功能:
if(strstr(request,"GET /redirect")!=NULL){
const char* response = "HTTP/1.1 302 Found\r\n"
"Location: http://www.baidu.com\r\n"
"Content-Length: 0\r\n"
"\r\n";
write(clientfd, response,strlen(response));
} else {
// 正常处理
}
浏览器访问 http://127.0.0.1:9090/redirect,会自动跳转到百度首页。
用途:指定 Body 的媒体类型(MIME 类型)。
常见值:
| Content-Type | 含义 | 应用场景 |
|---|---|---|
| text/html | HTML 页面 | 网页 |
| text/plain | 纯文本 | txt 文件 |
| application/json | JSON 数据 | API 响应 |
| application/x-www-form-urlencoded | 表单数据 | 表单提交 |
| multipart/form-data | 多部分数据 | 文件上传 |
| image/jpeg | JPEG 图片 | 图片资源 |
| image/png | PNG 图片 | 图片资源 |
| application/pdf | PDF 文档 | PDF 文件 |
示例:
响应 HTML:Content-Type: text/html;charset=utf-8
响应 JSON:Content-Type: application/json
响应图片:Content-Type: image/png
用途:指定 Body 的字节长度。
Content-Length: 1024
重要性:
用途:指定请求的主机名和端口。
Host: www.example.com:8080
为什么需要 Host:
示例:
同一台服务器(IP: 192.168.1.100)部署了三个网站:
- www.site1.com
- www.site2.com
- www.site3.com
请求 GET / HTTP/1.1 Host: www.site1.com → 返回 site1 的首页
请求 GET / HTTP/1.1 Host: www.site2.com → 返回 site2 的首页
用途:标识客户端的软件环境(浏览器类型、操作系统等)。
示例:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
拆解:
Windows NT 10.0:Windows 10 操作系统Win64; x64:64 位系统Chrome/91.0.4472.124:Chrome 浏览器版本 91应用场景:
为什么 User-Agent 这么复杂?
早期浏览器市场竞争激烈,为了兼容性,后来的浏览器会在 User-Agent 中加入"Mozilla"、"KHTML"、"Gecko"等字符串,假装自己是其他浏览器,以便网站正常工作。
1993 年 Mosaic 浏览器:User-Agent: NCSA_Mosaic/2.0
1994 年 Netscape Navigator(代号 Mozilla):User-Agent: Mozilla/1.0
1995 年 IE 浏览器(为了兼容,加入 Mozilla):User-Agent: Mozilla/2.0 (compatible; MSIE 3.0)
2003 年 Safari 浏览器(基于 KHTML 引擎):User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (KHTML, like Gecko) Safari/125
现在的 Chrome:User-Agent: Mozilla/5.0 ... AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91 Safari/537.36
所以现在所有浏览器的 User-Agent 都包含"Mozilla",非常魔幻。
用途:客户端存储少量数据,每次请求自动发送给服务器。
工作流程:
1. 客户端首次访问
GET / HTTP/1.1
2. 服务器设置 Cookie
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123;Path=/; HttpOnly
3. 客户端后续请求自动带上 Cookie
GET /profile HTTP/1.1
Cookie: session_id=abc123
4. 服务器根据 session_id 识别用户
Cookie 属性:
Path=/:Cookie 的有效路径Domain=example.com:Cookie 的有效域名Expires=...:过期时间HttpOnly:禁止 JavaScript 访问(防止 XSS 攻击)Secure:只在 HTTPS 下发送用途:标识请求的来源页面。
用户在 www.google.com 搜索,点击搜索结果跳转到 www.example.com
GET / HTTP/1.1
Host: www.example.com
Referer: https://www.google.com/search?q=example
应用场景:
客户端告诉服务器自己能接受什么类型的内容。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Accept:能接受的内容类型Accept-Encoding:能接受的压缩算法Accept-Language:能接受的语言q值表示优先级(0-1),默认 1.0。
HTTP 方法:
HTML 表单:
HTTP 状态码:
重定向:
常见 Header:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online