HTTP 方法详解

发布于 2025-12-18  18 次阅读


你可能也遇到过这种场景:

  • 前端同学说:“这个接口我用 GET 调一下就行吧?”
  • 后端说:“别啊,这个是删除操作……”
  • 结果上线后,某个页面被浏览器预加载了一下,用户数据竟然被删了。

听起来离谱,但它确实会发生。原因就在于:HTTP 方法不是“能请求通就行”,它是浏览器、缓存、代理、安全机制共同遵守的一套“约定”。

这篇文章我们就把 HTTP 方法讲清楚:
不仅知道“有哪些”,更要知道“为什么这么设计”“怎么用才安全”。


1. HTTP 方法是干什么的?(一句话讲透)

HTTP 方法(HTTP verbs)用来表达:客户端想对资源做什么操作

你可以把 URL 想成“资源地址”,把方法想成“对这个资源做的动作”:

  • /users/123 是用户 123 这个资源
  • GET /users/123 是“读取”
  • DELETE /users/123 是“删除”

这套表达的好处是:
浏览器、CDN、网关、爬虫、安全策略都能基于方法做出正确行为。


2. 先记住最常用的 5 个(80% 业务够用)

如果你只想先抓核心,记住这五个就够了:

  • GET:读数据
  • POST:提交/创建/执行动作
  • PUT:完整更新(替换)
  • PATCH:部分更新(改一点)
  • DELETE:删除

剩下的三个属于“辅助/进阶”:

  • HEAD:只拿响应头
  • OPTIONS:跨域预检 / 查询支持的方法
  • TRACE:诊断用(生产一般禁用)

3. 逐个方法讲清:它们的“性格”和“适用场景”

3.1 GET:最熟悉,但也最容易被用错

关键词:读取资源(只读)

典型用法:

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

GET 的“性格”:

  • 参数常在 URL 上(query string)
  • 通常没有请求体
  • 可以被缓存
  • 浏览器/爬虫/预加载可能会自动触发它

适合:

  • 列表/详情查询
  • 搜索、过滤
  • 获取页面内容

❌ 不适合(重点!):

  • 删除
  • 转账
  • 修改状态
    因为 GET 可能被“无意触发”,会带来安全事故(后面讲 CSRF)。

3.2 POST:提交数据(创建 or 动作)

关键词:提交给服务器处理

常见两种语义:

  1. 创建资源POST /users 创建一个用户
  2. 动作接口:登录、支付、导出、触发任务等

示例:

POST /api/users HTTP/1.1
Content-Type: application/json

{"name":"Wang Wu","email":"wangwu@example.com","age":28}

典型响应(创建):

HTTP/1.1 201 Created
Location: /api/users/3

POST 的“性格”:

  • 请求体里装数据(JSON/form-data 都行)
  • 通常非幂等:重复提交可能创建多个、重复扣费
  • 默认不可缓存

✅ 适合:

  • 提交表单
  • 创建资源
  • 上传文件
  • 登录注册、下单、支付等动作

实战提醒(很重要):

如果 POST 可能被重试(网络超时、客户端重发),建议做去重机制:比如 Idempotency-Key


3.3 PUT:完整更新(替换)

关键词:替换成“我给你的完整状态”

你可以把 PUT 理解成:

“我希望 /users/3 这个资源最终长这样”

示例:

PUT /api/users/3 HTTP/1.1
Content-Type: application/json

{"id":3,"name":"Wang Wu","email":"new@example.com","age":29}

PUT 的“性格”:

  • 幂等:同样的 PUT 发 10 次,最后结果一样
  • 通常要求提供“完整资源表示”
  • 有的系统允许资源不存在时创建(需要在 API 文档里明确)

✅ 适合:

  • 替换文档内容
  • 完整更新用户信息
  • 配置类资源整体更新

3.4 PATCH:部分更新(改一点点)

关键词:只改变化字段

示例:

PATCH /api/users/3 HTTP/1.1
Content-Type: application/json

{"age":30}

PATCH 的“性格”:

  • 更灵活:只传你要改的字段
  • 幂等性取决于你怎么定义
    • “把 age 设为 30”通常幂等
    • “age + 1”则不是幂等

适合:

  • 修改状态(enable/disable)
  • 改一个字段(昵称、头像、年龄)
  • 增量更新

3.5 DELETE:删除资源

示例:

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

常见响应:

  • 204 No Content(最常见)
  • 200 OK(想返回提示信息时)

DELETE 的“性格”:

  • 幂等:删一次和删很多次,最终都“没有这个资源”
  • 即使第二次返回 404,也不影响“最终状态一致”

适合:

  • 删除用户、文章、订单(视业务)
  • 清空缓存/资源

4. 三大“隐藏属性”:安全性 / 幂等性 / 可缓存性(核心中的核心)

很多人背方法背得很熟,但真正决定工程质量的是这三个属性。

4.1 安全性 Safe:不会改服务器状态

安全方法:GET、HEAD、OPTIONS
不安全方法:POST、PUT、PATCH、DELETE

安全性的重要意义:

  • 浏览器可能自动发请求(预加载、刷新、回退)
  • 爬虫会抓取链接
  • 所以“读操作”必须是安全的

经典反例(不要这么做)

GET /api/users/delete?id=123
GET /api/transfer?to=hacker&amount=1000

这类 GET 写操作,很容易被 CSRF 或误触发搞出事故。


4.2 幂等性 Idempotent:重复执行最终效果一样

幂等方法:GET、HEAD、PUT、DELETE、OPTIONS
POST 通常非幂等;PATCH 看实现。

为什么工程上非常重要?

  • 网络抖动、超时、弱网:客户端会重试
  • 网关也可能重放请求
  • 幂等能让重试“更安全”

POST 的幂等保护常用方案:Idempotency-Key
客户端带一个唯一 key,服务器保证同 key 只执行一次。


4.3 可缓存性 Cacheable:响应能否被缓存

默认可缓存:GET、HEAD
其他方法一般不缓存(避免写操作导致缓存混乱)。

缓存策略常用:

  • 私有数据:Cache-Control: private
  • 敏感数据:Cache-Control: no-store
  • 公共数据:Cache-Control: public, max-age=...

最常见坑:把用户私有信息当公共资源缓存,导致信息串给别人。


5. PUT vs PATCH:面试和实战都爱问的区别

一句话:

  • PUT:整体替换
  • PATCH:局部修改

更实战的理解:

  • PUT 更容易导致“没传的字段被覆盖/清空”(看你们怎么定义)
  • PATCH 更适合前端“只改一个字段”的场景
  • 如果你担心并发更新互相覆盖,PATCH 通常更安全一些

6. RESTful 设计:让 URL 像名词,让方法像动词

推荐的“最顺手”组合是:

GET    /api/users          获取用户列表
GET    /api/users/123      获取单个用户
POST   /api/users          创建用户
PUT    /api/users/123      完整更新
PATCH  /api/users/123      部分更新
DELETE /api/users/123      删除用户

一个简单但好用的原则:

路径表达资源(名词),方法表达操作(动词)。


7. 安全小节:最值得写进团队规范的 9 条

  1. 不要在 GET URL 里放敏感信息(密码、token)
  2. GET 只读,不做写操作
  3. 写操作用 POST/PUT/PATCH/DELETE,并做 CSRF 防护
  4. 禁用 TRACE
  5. 方法白名单:不支持直接 405
  6. 全站 HTTPS + HSTS
  7. 按方法做权限控制(读/写/删)
  8. 防止方法覆盖攻击(如 _method=DELETE
  9. 认真设置缓存:敏感数据 no-store


一昼一世界,一夜一星河。昼迷天未晓,夜尽终天明。