为什么使用HTTP PUT和DELETE方法而不是POST?

28 ruby-on-rails http delete-method

 new_story GET     /story/new(.:format)  {:action=>"new", :controller=>"stories"}
edit_story GET     /story/edit(.:format) {:action=>"edit", :controller=>"stories"}
     story GET     /story(.:format)      {:action=>"show", :controller=>"stories"}
           PUT     /story(.:format)      {:action=>"update", :controller=>"stories"}
           DELETE  /story(.:format)      {:action=>"destroy", :controller=>"stories"}
           POST    /story(.:format)      {:action=>"create", :controller=>"stories"}
Run Code Online (Sandbox Code Playgroud)

在网络工作中,我已经完成了其他技术,我只使用过GET和POST方法.但是在Rails中使用RESTful路由时,默认情况下,PUT和DELETE方法用于更新和销毁操作.使用PUT和DELETE的优点或需求是什么?我假设这些方法只是做POST的另一种方式 - 但为什么不坚持使用POST?

mip*_*adi 56

优点主要是语义,也可以在一定程度上简化URL.不同的HTTP方法映射到不同的操作:

POST   => create a new object
DELETE => delete an object
PUT    => modify an object
GET    => view an object
Run Code Online (Sandbox Code Playgroud)

然后,理论上,您可以使用相同的 URL,但使用不同的方法与它进行交互; 用于访问资源的方法定义了实际的操作类型.

但实际上,大多数浏览器只支持HTTP GET和POST.Rails使用HTML表单中的一些"技巧"来表现就好像发送了PUT或DELETE请求一样,即使Rails仍在使用GET或POST这些方法.(这解释了为什么你可能没有在其他平台上使用DELETE或PUT.)

  • 实际上,它非常简单.当使用Rails的方法生成表单时,如果指定PUT或DELETE,Rails实际上会POST表单,但它在表单中包含一个指定所需HTTP方法的隐藏字段.然后,在处理表单时,Rails会查找该隐藏字段,如果存在,它会(通过请求对象)报告表单是使用DELETE或PUT发送的,即使它确实是使用POST发送的.所以基本上,如果你指定DELETE,request.method会返回:delete,即使表单是POST.这一切都是自动发生的. (12认同)
  • @Jazz:因为它实际上会接受PUT和DELETE,如果你可以提供它们,但是对那些不能的东西(比如浏览器)做出回应. (2认同)
  • @OrthoHomeDefense:如果您有更好的答案或解释,请随时添加。 (2认同)

Han*_*Gay 9

这是HTTP 1.1规范"方法"部分 ; 它定义了许多方法,它们都有不同的好处和权衡.POST是最灵活的,但权衡很多:它不可缓存(因此互联网的其余部分无法帮助您扩展),它不安全或幂等,因此客户端不能只重新发送它会出错,并且它不再清楚你要完成的是什么(因为它非常灵活).我确信还有其他人,但这应该足够了.考虑到所有这些,如果HTTP规范定义了一个完全符合您的请求要求的方法,则没有理由发送POST.

原因POST是如此普遍,至少在历史上,Web浏览器仅支持GETPOST.由于GET被定义为安全且幂等(即使许多应用程序不遵守),修改数据的唯一安全方法是发送数据POST.随着AJAX和非浏览器客户端的兴起,这已不再适用.

顺便说一下,@ mipadi给出的映射是标准映射,但它不是唯一有效的映射.例如,Amazon S3用于PUT创建资源.使用的唯一原因POST是,如果客户端没有足够的知识来创建资源,例如,您使用关系数据库备份资源并使用人工代理键​​.

  • 在失败时重试; 如果你没有获得'ack`,你可以再次发送它 - 它保证与第一个工作时没有什么不同. (2认同)

Jos*_*osh 8

当你可以将其内容设置为零字节并且文件系统将其视为删除时,这有点像问为什么"删除"文件.HTTP一直支持除GET/POST以外的动词,但SOAP演变的方式有点扭曲了这些动词的原始含义.REST是一种更简单的回归基础方法,它使用动词,而不是在有效载荷内部发明一些新的动词概念.


Tra*_*ain 8

我只是想在接受的答案中添加一些内容,因为他对 的定义http verbs不正确。它们都有一个“应该”遵循的规范,您可以http verbs根据规范创建/更新/删除多个。

我将重点介绍W3RFC 2616中的一些重要内容

我将开始,PUT因为在我看来,它最令人困惑。

  • PUT is used for both create/update PUT updates by completely replacing the resource on the server with the resource sent in the request

例如

你给我的api打这个电话

PUT        /api/person
{
     Name: John,
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

我的服务器在服务器上有这个资源

{
     Name: Jane,
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

现在我现有的资源完全被你发送的资源所取代,这就是我服务器上的资源。

{
     Name: John,
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

所以如果你PUT只在正文中发送一封电子邮件

PUT        /api/person
{
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

我的服务器将完全替换实体

{
     Name: Jane,
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

{
     email: jdoe@hra.com
}
Run Code Online (Sandbox Code Playgroud)

而名字将消失。部分更新是为了,PATCHPOST无论如何我都用它。

  • One of the main reasons why we create/update with put is because it is idempotent.

这只是一个花哨的术语,它的基本定义是多个相同的请求对于单个请求是相同的。

例子

假设我PUT有一个文件,api/file如果源服务器没有找到该文件,它将创建一个。如果它确实找到了一个文件,它将用我发送的文件完全替换旧文件。这可确保创建和更新一个文件。如果不存在文件并且您调用了PUT5 次,第一次它会创建一个文件,然后其他 4 次它会用您发送的内容替换该文件。如果您调用 a POST5 次来创建,它将创建 5 个文件。

  • You PUT to that exact URI. If you don't you have to send a 301 (Moved Permanently) to the user and allow then make a choice whether or not to redirect the request. Most times the server you PUT to usually hosts the resource and takes care of updating it

这些是何时使用 PUT 的要点

至于POST关注

  • You can also create/update and then some...

正如我上面提到的,有一些关键的区别。

  • 帖子比较一般。以什么方式?其他一些示例包括通往其他协议的网关,它可以接收响应并将其发送到中间的某个数据处理程序,或者它可以扩展某种功能。
  • Post 没有“到确切的 URI 或通知”的限制,例如POST可以将资源附加到现有集合并决定它的存储位置。

现在我Delete为什么不POST呢?

当你DELETE的服务器不应该有应对的成功,除非你删除该资源或将它移动到难以接近的位置在响应发送的时间

为什么这很重要?如果你打电话DELETE但资源在被删除之前必须经过“批准”怎么办?如果删除可以被拒绝,您将无法发送成功的错误代码,并且如果您确实遵循了基本规范,这会让调用者感到困惑。只是一个例子,我相信你可以想到很多其他的。

我只是强调了一些关于何时使用通用的要点 Http verbs