PUT和POST的区别

我们都知道,PUT和POST是HTTP的两个方法(Method),都可以用来向HTTP服务器提交数据。似乎用哪个都可以,但其实两者还是有本质的区别的。

网上关于两者区别的文章比较多,但有相当一部分绝对是误导人。所以这次特意查看了RFC7231,来澄清二者的区别。

首先直接摘出RFC7231中的的部分关键原文:

The fundamental difference between the POST and PUT methods is highlighted by the different intent for the enclosed representation. The target resource in a POST request is intended to handle the enclosed representation according to the resource's own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server.

Proper interpretation of a PUT request presumes that the user agent knows which target resource is desired. A service that selects a proper URI on behalf of the client, after receiving a state-changing request, SHOULD be implemented using the POST method rather than PUT.

上面这两段描述的关键词就是“idempotent”(幂等),理解了这个词就理解了二者的本质区别。下面就围绕这个词从以下几个角度分析PUT和POST的区别。

1、使用PUT时,必须明确知道要操作的对象,例如:

PUT /customer/doc/1

{

"name": "John Doe"

}

上面的PUT请求明确是对编号为1的文档进行操作,这里编号为1的文档就是要操作的对象。如果该文档不存在,就创建该文档;如果文档已经存在,就直接整个替换文档内容

2、 有人可能会质疑,上面的例子用POST也可以实现。没错,如果用将上例中的PUT接口改成POST接口,就是这样:

POST /customer/doc/

{

"name": "John Doe"

}

注意这里有一个重要的不同,这里POST请求并不知道要操作的对象,它只是向HTTP服务器提交一篇新文档,由HTTP服务器为该文档产生一个编号。这就是上面从RFC7231中摘出的第二段文字所描述的含义。

3、有人可能会继续质问:用POST也可以用来修改目标资源对象阿。说得还是没错。还是沿用上面的例子,稍作如下改动:

POST /customer/doc/1

{

"description": "I am a student"

}

这里的含义是给编号为1的文档增加一个属性“description”。注意这里有两个不同:(1)这里编号为1的文档必须是已经存在的文档,否则必须使用PUT;(2)这里是对目标对象的部分修改。只是增加了一个新属性“description”,之前的属性“name”不受影响。

4、最后简要总结一下,使用PUT时,必须明确知道要操作的对象,如果对象不存在,创建对象;如果对象存在,则全部替换目标对象。同样POST既可以创建对象,也可以修改对象。但用POST创建对象时,之前并不知道要操作的对象,由HTTP服务器为新创建的对象生成一个唯一的URI;使用POST修改已存在的对象时,一般只是修改目标对象的部分内容。

经过了以上4条的分析之后,对PUT和POST的区别应该很清楚了吧?再强调一遍,PUT是“idempotent”(幂等),意味着相同的PUT请求不管执行多少次,结果都是一样的。但POST则不是。就类似于"x=1"这条语句是幂等的,因为无论执行多少次,变量x的值都是1;但"x++"就不是幂等的,因为每执行一次,变量x的值都不一样。

当然,这里讲的都是规范,都是最佳实践(best practise)。如果你在实际开发中,不按这个来,没有人能管得了你;但是当你的REST API要开放给别人使用时,就会和大家所接受的“普世价值”违背,很可能就会发生各种问题。

如果还有疑问,欢迎留言交流讨论:)。

--END--

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180114G09Y6F00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券