HTTP方法中的幂等性是什么?

115

我已经阅读了HTTP文档,但是我无法理解什么是幂等性。有人可以帮忙吗?


1
你是在问什么是“幂等”,还是在问为什么“幂等”动词很有用? - Phrogz
3
请参考《两个将军问题》视频,了解为什么“幂等性”很有用。 - Lord Elrond
1
不错的链接参考,但它会直接跳转到赞助广告中间。巧合吗? :) - houcros
5个回答

188
“幂等性”是HTTP方法的一种属性。
如果使用某个请求方法进行多次相同请求,其对服务器的预期影响与单个请求的影响相同,则该请求方法被认为是“幂等的”。值得一提的是,幂等性关注的是对服务器上资源状态产生的影响,而不是客户端接收到的响应状态码。
例如,考虑“DELETE”方法,它被定义为幂等。现在假设一个客户端执行了一个“DELETE”请求来删除服务器上的一个资源。服务器处理请求,资源被删除并返回204。然后客户端重复相同的“DELETE”请求,由于资源已经被删除,服务器返回404。
尽管客户端接收到的状态码不同,但单个“DELETE”请求产生的效果与对同一URI进行多个“DELETE”请求的效果相同。

最后,使用幂等方法的请求如果在客户端能够读取服务器响应之前发生通信故障,则可以自动重复。即使原始请求成功,客户端也知道重复请求将产生相同的预期效果,尽管响应可能会有所不同。

RFC 7231

让我们来看看RFC 7231,这个文档定义了HTTP/1.1协议的语义和内容。请参见以下引用(我的部分是高亮显示的)。

HTTP方法可以是安全的

4.2.1. 安全方法

如果请求方法的定义语义基本上是只读的,则认为它们是“安全”的;也就是说,客户端在将安全方法应用于目标资源时不会请求或期望在源服务器上产生任何状态更改。[...]

安全方法的这个定义并不会阻止实现包含潜在有害的行为,这些行为并非完全只读,或者在调用安全方法时会导致副作用。然而,重要的是客户端没有请求附加行为,因此不能对其负责。[...]

在本规范中定义的请求方法中,GETHEADOPTIONSTRACE方法被定义为安全方法。[...]

并且/或幂等性

4.2.2. 幂等方法

如果使用相同的请求方法多次请求服务器,产生的效果与只请求一次相同,则该请求方法被认为是“幂等的”。在本规范定义的请求方法中,PUTDELETE和安全请求方法都是幂等的。[...]

与安全的定义类似,幂等属性仅适用于用户请求的内容;服务器可以单独记录每个请求,保留修订控制历史记录或为每个幂等请求实现其他非幂等副作用。 [...]

总结一下,HTTP方法被分类为以下

+---------+------+------------+
| Method  | Safe | Idempotent |
+---------+------+------------+
| CONNECT | no   | no         |
| DELETE  | no   | yes        |
| GET     | yes  | yes        |
| HEAD    | yes  | yes        |
| OPTIONS | yes  | yes        |
| POST    | no   | no         |
| PUT     | no   | yes        |
| TRACE   | yes  | yes        |
+---------+------+------------+  

RFC 5789

RFC 5789 定义了 PATCH 方法,该方法既不安全也不幂等。然而,为了防止冲突,PATCH 请求可以以幂等的方式发出,如下所述:

发出PATCH请求时,可以以幂等的方式发出,这也有助于防止在类似时间范围内对同一资源进行两个PATCH请求之间发生冲突造成不良后果。多个PATCH请求引起的冲突可能比PUT冲突更危险,因为某些补丁格式需要从已知基点操作,否则它们将破坏该资源。使用这种类型的补丁应用程序的客户端应使用条件请求,以便如果自上次访问资源以来已更新资源,则请求将失败。例如,客户端可以在PATCH请求的If-Match头中使用强ETag


1
DELETE 如何成为幂等方法?如果成功,通常会返回 200 (OK)204 (No Content) - Nisarg Patil
5
@NisargPatil 请参考这个问题 - cassiomolin
1
上面的问题答案不言自明。谢谢 :) - Nisarg Patil
“TRACE” 不是一种总是安全的方法,它可能会改变源状态。 - Anil Bhaskar
1
@C.J. 我明白了。我原以为PUT可以被重新发送而不用担心,而POST则不能,可能是因为HTTP本身的某些功能原因。现在看来,我们只需要遵守HTTP标准,行为完全取决于服务器的实现方式。 - mangusta
显示剩余3条评论

9

我的理解是,幂等性与结果(服务器响应)无关,而与单次或多次调用后的服务器状态有关。

假设您想通过调用来删除服务器上的一个资源

DELETE /resource/123

调用可能会返回HTTP响应200 OK,并在第一次调用中将已删除的资源作为有效载荷返回。在第二次调用中,响应将是204 NO_CONTENT,因为第一次调用已经删除了该资源。
每个请求后,服务器状态都是相同的,因此满足幂等性。HTTP / 1.1对响应没有任何规定。

如果具有该方法的多个标识请求的预期效果与单个标识请求的效果相同,则认为请求方法是“幂等”的。


3
Nit: 204 No Content这个响应状态码并不是一个很好的指示资源已被删除的代码。 - Evert
@Evert - 你为什么这么说? - MasterJoe
2
@MasterJoe,我稍微撤回一下之前的说法。现在的建议是,即使只有第一个请求实际上删除了资源,多个幂等请求返回相同的状态也是可以接受的。有时候204状态码会被误解为“该资源已被删除”,这可能就是我提到这个问题的原因……但我的评论是错误的。 - Evert

-1

简述

幂等性:GET,PUT:为什么?

  • GET 如果递归地触发 exact /resource/123 它将会给出相同的结果

  • PUT 如果递归地触发 exact /user/123 它将会给出相同的结果

非幂等性:DELETE,POST:为什么?

  • DELETE 如果递归地触发 exact /user/123 它将会第二次给出不同的结果(404或NOT_FOUND)

  • POST 如果递归地触发 exact /user/(id由服务器分配) 它将会每次给出不同的结果

结论:根据 HTTP 文档,DELETE 具有幂等性,但其行为是非幂等的。

如果请求返回相同的结果,则对于完全相同的 URL 进行递归触发。


13
DELETE 的定义是幂等的。 - Julian Reschke
14
是的,它是幂等的。 "如果一种请求方法对于多个相同请求的服务器预期效果与单个请求的效果相同,则认为该请求方法是“幂等的”。" 对于DELETE方法来说就是这样。状态码并不重要,资源的状态才是关键。 - Julian Reschke
5
可以的。重要的是,在请求之后,资源已经消失了。 - Julian Reschke
6
我认为幂等性不是关于“产生什么结果”的问题,而是关于状态或原始/服务器的问题。 - Anil Bhaskar
1
在幂等性的情况下,状态码并不重要。最终的服务器状态才是关键。 - Julian Reschke
显示剩余9条评论

-3

幂等的HTTP方法是指可以多次调用而不会产生不同结果的HTTP方法。无论该方法只被调用一次还是十次以上,结果应该是相同的。这实际上意味着成功执行请求的结果与其执行次数无关。例如,在算术中,将零加到一个数字上是幂等操作。

POST方法不是幂等的。 GET、PUT、DELETE、HEAD、OPTIONS和TRACE是幂等的。

1>POST -->每次调用此方法都会给出不同的结果 为什么-->考虑一个场景,您正在创建新资源 每次调用此方法都会导致创建新资源,从而每次都会给您不同的结果,因此,POST(简单地说是“插入”)是非幂等方法。

2>其他方法将给您相同的结果


2
幂等性与HTTP方法的响应无关,请查看此帖子上接受的答案。 - Nagesh Tripathi
@NageshTripathi 没有提到请求的响应,只提到了服务器上的结果(或者说受影响的资源/实体),这正确地识别了幂等性。他们甚至给出了一个数学类比,很好地描述了操作模式。 - hurikhan77

-12

幂等方法(GET,OPTIONS)不会改变服务器上的任何内容(除了可能添加日志条目)。非幂等方法(PUT,POST,DELETE)会更改用于填充Web页面中内容或在其他地方产生影响(例如移动起重机,转移资金,发送电子邮件)的数据。


7
并不完全正确。“幂等”意味着您可以重复请求,结果应该是相同的。PUT和DELETE也属于这个类别。 - Gerard van Helden
你在这里描述的正是HTTP规范中“安全方法”的定义。幂等方法是安全方法的超集(包括所有安全方法以及PUT和DELETE)。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接