HTTP方法的安全性和幂等性

说明:如有侵权,请联系删除

HTTP方法的安全性和幂等性

HTTP 协议规定了不同方法的安全特性和幂等特性,作为服务提供者的服务器必须为客户端提供这些特性。

安全性(Safety) :

仅指该方法的多次调用不会产生副作用(即不会改变资源状态),不涉及传统意义上的"安全"。

安全的方法不会修改资源状态,尽管多次调用的返回值可能不同(例如资源被其他非安全方法修改过)。

幂等性(Idempotence) :

指该方法多次调用返回的效果(形式)一致,客户端可以重复调用并期望获得相同的结果。

幂等的含义类似于编程语言中的 setter 方法:一次调用和多次调用产生的效果一致,都是对一个变量进行赋值。

两者的区别容易混淆,简单理解如下:

特性 判断标准 示例
安全性 发送请求是否会改变资源状态(不会改变 → 安全) GET、HEAD、OPTIONS
幂等性 多次执行是否产生相同效果(不会改变 → 幂等) GET、PUT、DELETE、HEAD、OPTIONS

安全性与幂等性总结图

可以认为安全的方法都是只读方法 (GET、HEAD、OPTIONS),不会改变资源状态,因此它们同时也是幂等的。


DELETE方法的幂等性

DELETE 方法的语义表示删除服务器上的一个资源。

第一次删除成功后资源就不存在了,资源状态发生了改变,因此 DELETE 方法不具备安全性。

然而 HTTP 协议规定 DELETE 方法是幂等的:

每次删除该资源都要返回状态码 200 OK。

服务器端若要实现幂等的 DELETE 方法,必须记录所有已删除资源的元数据(Metadata),否则第二次删除时返回的响应可能是 404 Not Found,从而破坏幂等性。


PUT与POST的区别

PUT 和 POST 方法语义中都包含修改资源状态的意思,因此都不是安全的。

方法 是否安全 是否幂等 特点
PUT 否 是 重复执行结果相同(覆盖)
POST 否 否 重复执行结果不同(新建)

为什么 PUT 是幂等的而 POST 不是?

HTTP 协议规定:

  • POST 方法 :URL 指向资源的父级资源 ,待创建资源的 ID 信息在请求体中携带 。
    → 重复提交 POST 请求可能会创建多个不同资源。
  • PUT 方法 :URL 直接指向待修改资源。
    → 重复提交 PUT 请求只会对该 URL 指定的资源起作用,也就是只会创建或更新一个资源。

因此:

  • PUT 是幂等的:多次调用的结果一致(更新或覆盖相同资源)。
  • POST 不是幂等的:多次调用可能产生多个不同资源。

PUT 与 POST 的使用区别

在实践中有几种常见观点:

  1. 用 POST 创建资源,用 PUT 更新资源;
  2. 用 PUT 创建资源,用 POST 更新资源;
  3. PUT 与 POST 都可用于创建或更新。

这些争论其实不是"风格"问题,而是"语义"问题。
是否使用 PUT 或 POST,取决于操作是否幂等。

"Methods can also have the property of idempotence in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request."

即:如果一个方法重复执行多次,产生的效果是一样的,那么它就是幂等的。


举例说明

假设有一个博客系统提供一个 Web API:

http://superblogging/blogs/post/{blog-name}

发送一个 HTTP PUT 或 POST 请求,Body 中包含博文内容。

问题:该使用 PUT 还是 POST?

取决于服务的行为是否幂等:

  • 如果发送两次相同请求会生成两个不同的帖子 → POST(非幂等)
  • 如果后一个请求覆盖了前一个帖子 → PUT(幂等)

总结对比表

方法 是否安全 是否幂等 典型用途
GET ✅ 是 ✅ 是 获取资源
HEAD ✅ 是 ✅ 是 获取资源元数据
OPTIONS ✅ 是 ✅ 是 查询支持的方法
POST ❌ 否 ❌ 否 创建子资源、提交表单
PUT ❌ 否 ✅ 是 创建/更新指定资源
DELETE ❌ 否 ✅ 是 删除资源

结论:

  • 安全性:不修改资源状态。
  • 幂等性:多次调用效果一致。
  • PUT 与 DELETE 是幂等但不安全;
  • GET、HEAD、OPTIONS 既安全又幂等;
  • POST 既不安全也不幂等。
相关推荐
吴声子夜歌7 小时前
Nginx应用与运维——Nginx HTTP模块详解(动态赋值功能模块)
运维·nginx·http
傲世仙尊13 小时前
HTTP请求与应答-URL全网唯一文件路径报文结构与短连接
网络·网络协议·http
傲世仙尊1 天前
HTTP起步-URL域名解析与协议的本质
网络·网络协议·http
ControlRookie1 天前
第27篇_综合排障|从现象反查状态、错误码、指标和连接快照
http·codesys·plc通信
天天喝旺仔2 天前
gRPC 底层原理:HTTP/2 多路复用、Protobuf 序列化与四种流模式
分布式·http·微服务·rpc
liangshanbo12152 天前
面试题:页面需要发起大量 Ajax / HTTP 请求时,如何优化请求性能?
前端·http·ajax
零域码客2 天前
零基础Python爬虫入门:从HTTP协议到 requests + BeautifulSoup 实战
爬虫·python·http
被摘下的星星2 天前
HTTP 状态码 和 网络端口号
网络·网络协议·http
zxanz13 天前
https 的基本原理是什么样的?
网络协议·http·https
码匠许师傅3 天前
【C++三方组件】cpp-httplib:一个头文件起 HTTP 服务
开发语言·c++·http