3、HTTP 协议基础:请求方法、状态码、请求头与响应头

说实话,HTTP 协议这东西,天天打交道。但你真让我讲透,我估计不少同学会卡在「GET 和 POST 到底啥区别」这种问题上。

我当年刚入行时,也犯过傻。有一次写接口,把所有操作都用了 GET,结果被运维大哥骂了一顿——「你 GET 请求还能删数据?!」嗯,从那以后,我才开始认真研究 HTTP 的请求方法。

3.1 请求方法:你用什么方式跟服务器说话?

HTTP 定义了多种请求方法,最常用的就四个:GET、POST、PUT、DELETE。说白了,就是你对资源要做什么操作。

方法 含义 幂等性 请求体
GET 获取资源 是 无
POST 创建资源 否 有
PUT 更新/替换资源 是 有
DELETE 删除资源 是 通常无

关键点:GET 请求的参数拼在 URL 里,有长度限制(浏览器一般 2KB 左右)。POST 的参数在请求体里,理论上没限制。但这不是最重要的区别——语义才是。

我见过不少新手把 POST 当 GET 用,或者反过来。你想想看,如果你用 GET 去创建一个订单,服务器返回 200 但订单没创建成功,那问题出在哪?语义不对。

3.1.1 GET:查东西

GET 是最简单的。浏览器输入网址回车,就是 GET。它不应该有副作用——也就是说,你刷新一百次,结果应该一样。

GET /api/users?page=1&size=20 HTTP/1.1
Host: example.com

3.1.2 POST:造东西

POST 用来创建资源。每次调用都可能产生不同的结果——比如你提交两次订单,会生成两个订单号。

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "name": "张三",
  "email": "zhangsan@example.com"
}

我的习惯:POST 请求一定要做防重复提交。我曾经在一个支付接口上吃过亏,用户连续点了两次「提交」,结果扣了两次钱。后来我加了幂等性校验,用唯一请求号去重。

3.1.3 PUT:改东西

PUT 是幂等的。你调一次和调一百次,结果一样。它通常用来全量更新资源。

PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "name": "李四",
  "email": "lisi@example.com"
}

3.1.4 DELETE:删东西

DELETE 也是幂等的。第一次删掉资源,第二次再删,服务器应该返回 404 或者 204,但不会报错。

DELETE /api/users/123 HTTP/1.1
Host: example.com

3.2 状态码:服务器在说什么?

状态码是服务器给你的「回话」。我刚开始看状态码时,只记得 200 和 404。后来踩坑多了,才明白每个状态码都有它的脾气。

3.2.1 2xx:一切正常

  • 200 OK:请求成功。最常用的。
  • 201 Created:资源创建成功。POST 请求常用。
  • 204 No Content:请求成功,但没返回内容。DELETE 常用。

3.2.2 4xx:你搞错了

  • 400 Bad Request:请求格式不对。比如 JSON 解析失败。
  • 401 Unauthorized:没登录。需要认证。
  • 403 Forbidden:登录了但没权限。
  • 404 Not Found:资源不存在。
  • 405 Method Not Allowed:方法不支持。比如只允许 POST,你用了 GET。
  • 429 Too Many Requests:请求太频繁。限流了。

避坑指南:我曾经在项目里把 401 和 403 混用了。结果前端判断「未登录」时,后端返回了 403,导致用户一直弹「权限不足」而不是跳转登录页。记住:401 是没认证,403 是认证了但没授权。

3.2.3 5xx:服务器炸了

  • 500 Internal Server Error:服务器内部错误。最常见。
  • 502 Bad Gateway:网关或代理出问题。
  • 503 Service Unavailable:服务暂时不可用。比如过载或维护。
  • 504 Gateway Timeout:网关超时。

5xx 错误,说白了就是后端出问题了。我建议你在接口文档里明确约定:4xx 是客户端问题,5xx 是服务端问题。这样排查起来快很多。

3.3 请求头与响应头:藏在信封上的信息

HTTP 头部就像信封上的地址和邮戳。你光看正文不够,还得看头信息。

3.3.1 常见请求头

请求头 作用 示例
Content-Type 告诉服务器请求体的格式 application/json
Authorization 携带认证信息 Bearer xxx
Accept 告诉服务器客户端能接收的格式 application/json
User-Agent 客户端标识 Mozilla/5.0...
Cookie 携带会话信息 session_id=abc123

3.3.2 常见响应头

响应头 作用 示例
Content-Type 告诉客户端响应体的格式 application/json; charset=utf-8
Set-Cookie 设置 Cookie session_id=abc123; Path=/
Cache-Control 缓存策略 no-cache, max-age=3600
Access-Control-Allow-Origin CORS 跨域设置 *

我的经验:Content-Type 这个头最容易出错。有一次前端传了 JSON,但 Content-Type 写成了 text/plain,后端解析直接报 400。排查了半天才发现是头写错了。所以,请求头和响应头一定要对齐。

3.4 知识体系图

下面这张图,是我自己梳理的 HTTP 协议基础结构。你看一眼,就能把请求方法、状态码、头部串起来。

HTTP 协议基础 请求方法 GET - 获取资源 POST - 创建资源 PUT - 更新资源 DELETE - 删除资源 状态码 2xx - 成功 4xx - 客户端错误 5xx - 服务端错误 请求头/响应头 Content-Type Authorization Cache-Control Cookie / Set-Cookie 三者共同构成 HTTP 请求-响应的完整语义 方法决定操作 → 状态码反馈结果 → 头部携带元数据

嗯,这张图其实就讲了三件事:用什么方法、得到什么结果、头里带了什么信息。你把这三点串起来,HTTP 协议的基础就算拿下了。

总结一下:

  • GET 查、POST 增、PUT 改、DELETE 删——语义要清晰
  • 2xx 成功、4xx 你错、5xx 我错——责任要分明
  • 请求头告诉服务器「我要什么」,响应头告诉客户端「我给你什么」——沟通要对齐

我个人习惯在项目初期就把这些约定写进接口文档里。别等到联调时才发现「哎,你这个状态码怎么返回的是 200 但 body 里是错误信息?」——那可就晚了。

可可精品资料库