我很难理解为什么 PATCH 在 PUT 所在的地方不安全。Aso 幂等部分 - 如果我更新资源的一个字段,该字段在更新后不会返回相同的值吗?
4 回答
这是不安全的,因为通常您无法在不更改资源的情况下安全地执行 PATCH 请求(这就是它的用途)。
那么为什么 PATCH与 PUT 相比不是幂等的呢?这是因为应用更改的方式很重要。如果您想更改name
资源的属性,您可以发送类似{"name": "foo"}
有效负载的内容,这确实是幂等的,因为执行此请求任意次数都会产生相同的结果:资源name
属性现在是“foo”。
但是 PATCH 在如何更改资源方面更为通用(查看此定义以了解如何应用 JSON 补丁)。例如,它也可能意味着移动资源,看起来像这样:{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
. 这个操作显然不是幂等的,因为第二次调用会导致错误。
因此,虽然大多数 PATCH 操作可能是幂等的,但也有一些不是。
对其他答案的评论:幂等性是通过连续多次重复操作来定义的。说某事不是幂等的,因为如果在两者之间或并行执行其他操作时效果不同,这不是一个有效的论点(如果是这种情况,通常没有操作是幂等的)。从数学上讲,幂等变换是一种产生相同结果的变换,无论您应用它的频率如何(例如旋转 360 度)。当然,如果您在两者之间应用任何其他操作,两个 360 度旋转可能会产生不同的结果。
我最近开始查看 Patch 是否是幂等的,在阅读了 JSON 补丁格式之后,我了解到如果使用 Patch 方法应用添加操作,则请求完全有可能是非幂等的,因为它可以将新值添加到如果多次发出相同的请求,则为现有资源。
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
PATCH 更改资源属性。更改可能需要属性的具体先前值,这使其成为非幂等的。
From Name=John to Name=Gargantua.
重复应用后,名称将是 Gargantua 并且补丁将失败,因为在更改之前它要求名称为“John”
"from Name=John"
首先,PUT
也不安全。
安全方法是不修改资源的 HTTP 方法。例如,在资源 URL 上使用 GET 或 HEAD,永远不要更改资源。
由于PUT
请求(PATCH 也是如此)更新了资源,所以它不能被缓存,因此它不是安全的。
PUT
request 是幂等的,或者我应该说PUT
request 应该是幂等的。
幂等 HTTP 方法是一种可以多次调用而没有不同结果的 HTTP 方法。该方法是否只被调用一次或十次都没有关系。结果应该是一样的。同样,这仅适用于结果,而不适用于资源本身。这仍然可以被操纵(如更新时间戳,只要此信息未在(当前)资源表示中共享)。
请求幂等背后的想法PUT
是,如果对资源的更新调用失败,客户端可以再次进行相同的调用,而不会导致任何不良或不一致的状态。PUT
request 应该始终在GET
对资源的请求之前,并且如果并且如果此后只有资源没有更改,则应该成功。详细说明:-通过类似的答案之一-并发环境中的幂等 PUT 请求
现在PATCH
请求旨在仅更新选择性字段,预计不会获取资源表示。因此,对请求的多次调用PATCH
可能最终导致资源状态发生不良变化。因此它不是IDEMPOTENT
。
例如:- 有资源Person
请求 1:PATCH /person/1 {'age': 10} - 将资源的年龄更新为 10
现在假设其他一些并行请求改变了资源的状态,比如说
请求 2:PATCH /person/1 {'age': 19} - 将资源的年龄更新为 19
现在,如果再次发送请求 1,它将再次将资源年龄更新为 10,从而导致不良结果。
它可以通过使用 etags 或 If Modified since 标头使其具有幂等性。