HTTP 协议核心:请求方法、状态码与头信息
说实话,HTTP 协议这东西,你天天在用,但真把它吃透的人不多。
我记得刚入行那会儿,总觉得 HTTP 就是发个请求、收个响应,有啥好学的?直到有一次线上事故——我写了个 DELETE 接口,前端却用 GET 来调用,结果数据全被缓存了,用户删了东西刷新页面还在。嗯,从那以后,我再也不敢小看这几个方法了。
一、HTTP 请求方法:你每天都在用,但用对了吗?
HTTP 定义了若干种请求方法,每种方法都有它的语义和约定。说白了,就是告诉服务器「我想干嘛」。
1. GET:获取资源
GET 是最常用的方法。它的特点是:幂等、安全、可缓存。
我在项目中遇到过一个问题:有人用 GET 传了 10MB 的 JSON 数据。结果呢?浏览器直接报 414 URI Too Long。GET 的 URL 长度是有限制的,一般 2KB 到 8KB 不等,取决于浏览器和服务器。
2. POST:创建资源
POST 是非幂等的。什么意思?你发两次 POST,服务器可能会创建两条记录。
我曾经踩过一个坑:用户连续点了两次提交按钮,结果数据库里多了两条一模一样的订单。后来我加了幂等性校验,才解决了这个问题。
3. PUT:更新资源
PUT 是幂等的。你发一次和发一百次,结果是一样的。
我个人习惯用 PUT 来做全量更新。比如更新用户信息,前端传什么,后端就覆盖什么。但要注意:如果只传了部分字段,没传的字段会被置空。这就是所谓的「全量替换」。
4. DELETE:删除资源
DELETE 也是幂等的。删一次和删一百次,结果都是「已删除」。
但有个细节:第一次 DELETE 返回 200,第二次可能返回 404(资源已不存在)。这其实是合理的,因为资源状态变了。
| 方法 | 幂等 | 安全 | 可缓存 | 典型场景 |
|---|---|---|---|---|
| GET | 是 | 是 | 是 | 查询列表、获取详情 |
| POST | 否 | 否 | 否 | 创建订单、提交表单 |
| PUT | 是 | 否 | 否 | 更新用户信息 |
| DELETE | 是 | 否 | 否 | 删除资源 |
二、状态码:服务器在跟你说话
状态码是服务器给你的「暗号」。你想想看,服务器收到请求后,总得告诉你结果吧?状态码就是干这个的。
200 OK:一切正常
这是最理想的状态。请求成功,响应体里就是你要的数据。
404 Not Found:资源不存在
这个大家太熟悉了。但你知道吗?404 不一定是真的「不存在」。有时候是 URL 写错了,有时候是权限不够但服务器故意返回 404 来隐藏资源。
我曾经排查过一个 bug:用户明明有权限,但接口一直返回 404。查了半天,发现是 Nginx 配置里把路径写错了。嗯,这种低级错误,谁还没犯过呢?
500 Internal Server Error:服务器炸了
这是后端工程师最怕看到的。服务器内部出错了,但具体是什么错?不知道。所以生产环境一定要做好日志记录,不然 500 就是个大黑盒。
除了这三个,还有几个常用的:
- 201 Created:POST 创建成功时返回,比 200 更语义化
- 204 No Content:DELETE 成功时返回,响应体为空
- 301/302:重定向,常用于 URL 迁移
- 401 Unauthorized:没登录
- 403 Forbidden:登录了但没权限
- 429 Too Many Requests:请求太频繁,被限流了
三、请求头与响应头:藏在背后的秘密
头信息是 HTTP 的「元数据」。你想想看,光有请求方法和 URL 是不够的,服务器还需要知道:你的浏览器是什么?你支持什么语言?你希望响应是什么格式?这些信息都放在头里。
常见的请求头
| 请求头 | 作用 | 示例 |
|---|---|---|
| Content-Type | 告诉服务器请求体的格式 | application/json |
| Authorization | 携带认证信息 | Bearer xxxxx |
| Accept | 告诉服务器你期望的响应格式 | application/json |
| User-Agent | 标识客户端信息 | Mozilla/5.0... |
常见的响应头
| 响应头 | 作用 | 示例 |
|---|---|---|
| Content-Type | 告诉客户端响应体的格式 | application/json; charset=utf-8 |
| Cache-Control | 控制缓存行为 | max-age=3600 |
| Set-Cookie | 设置 Cookie | sessionId=abc123 |
| Access-Control-Allow-Origin | CORS 跨域控制 | * |
四、知识体系总览
下面这张图,把 HTTP 协议的核心内容串起来了。你一看就明白:请求方法、状态码、头信息,这三者是怎么配合的。
五、实战:一个完整的 HTTP 请求
光说不练假把式。我们来看一个真实的例子。
假设你要调用一个用户查询接口:
// 请求
GET /api/users/123 HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json
User-Agent: Mozilla/5.0
// 响应
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: max-age=60
Set-Cookie: sessionId=abc123; Path=/; HttpOnly
{
"id": 123,
"name": "张三",
"email": "zhangsan@example.com"
}
你看,请求方法用了 GET,状态码是 200,请求头里带了认证信息,响应头里指定了格式和缓存策略。这就是一个标准的 HTTP 交互。
嗯,今天就聊到这儿。下一节我们讲 RESTful API 设计,到时候你会更深刻地理解这些方法该怎么用。
公众号:蓝海资料掘金营,微信deep3321