为什么要使用HTTP POST或DELETE而不是GET来删除?

我一直在通过微软的ASP.NET MVC教程,结束在这个页面

http://www.asp.net/learn/mvc/tutorial-32-cs.aspx

以下是对本页底部的说明:

通常,在调用修改Web应用程序状态的操作时,您不希望执行HTTP GET操作。 执行删除时,您想要执行HTTP POST,或者更好的是执行HTTP DELETE操作。

这是真的? 任何人都可以为这个陈述背后的理由提供更详细的解释吗?

编辑

维基百科声明如下:

有些方法(例如,HEAD,GET,OPTIONS和TRACE)被定义为安全的,这意味着它们仅用于信息检索,不应该改变服务器的状态。

相比之下,诸如POST,PUT和DELETE等方法用于可能会在服务器上导致副作用的操作

Jon Skeet的答案是规范的答案。 但是:假设你有一个链接:

href = "\myApp\DeleteImportantData.aspx?UserID=27" 

谷歌机器人来索引你的网页? 那会发生什么?

GET通常没有副作用 – 换句话说,它不会改变状态。 这意味着结果可以caching,书签可以安全地进行。

来自HTTP 1.1 RFC 2616

实现者应该意识到,软件代表用户在互联网上的交互,并且应该小心让用户意识到他们可能采取的任何可能对他们自己或他人意想不到的意义的行为。

具体而言,公约已经确定GET和HEAD方法不应该具有除了检索之外采取行动的意义。 这些方法应该被认为是“安全的”。 这允许用户代理以一种特殊的方式表示其他方法,例如POST,PUT和DELETE,以使用户意识到可能不安全的动作被请求的事实。

当然,由于执行GET请求,不可能确保服务器不会产生副作用; 实际上,一些dynamic资源认为是一个function。 这里的重要区别是用户没有要求副作用,所以不能为他们负责。

除了纯粹的幂等性问题,还有一个实际的方面:蜘蛛/机器人/爬虫等将遵循超链接。 如果您将“删除”操作作为执行GET的超链接,那么Google可以快速删除所有数据。 见“ 末日之蜘 ”。

有了post,这不是一个风险。

请在这里看到我的答案 。 这同样适用于这个问题。

  • 预取:很多网页浏览器都会使用预取。 这意味着它会在你点击链接之前加载一个页面。 预计您稍后将点击该链接。
  • 机器人:有几个机器人扫描和索引互联网的信息。 他们只会发出GET请求。 由于这个原因你不想从GET请求中删除某些东西。
  • caching: GET HTTP请求不应该改变状态,它们应该是幂等的。 幂等意味着一次发出一个请求,或多次发出一个请求给出相同的结果。 即没有副作用。 由于这个原因,GET HTTP请求与caching紧密相关。
  • HTTP标准是这样说的 :HTTP标准说明了每个HTTP方法的用途。 有几个程序是为了使用HTTP标准而build立的,他们认为你会按照你应该的方式来使用它。 所以如果你不遵循的话,你会有一些随机程序中的未定义的行为。

另一个例子..

 http://example.com/admin/articles/delete/2 

这将删除文章,如果您login并具有正确的权限。 如果您的网站接受评论,例如用户将该链接提交为图片; 像这样:

 <img src="http://example.com/admin/articles/delete/2" alt="This will delete your article."/> 

然后,当您作为pipe理员用户自己浏览网站上的评论时,浏览器将尝试通过向该URL发送请求来获取该图像。 但是,因为您在浏览器正在login,所以文章将被删除。

您甚至可能没有注意到,没有查看源代码,因为大多数浏览器不能显示任何东西,如果它找不到图像。

希望是有道理的。

除了蜘蛛和请求必须是幂等的,获取请求也存在安全问题。 有人可以轻松地向用户发送电子邮件

 <img src="http://yoursite/Delete/Me" /> 

在文本和浏览器将愉快地去尝试和访问资源。 使用POST并不能解决这种问题(因为你可以很容易地将表单贴在JavaScript中),但这是一个好的开始。

关于这个话题(HTTP方法的用法),我推荐阅读这个博客文章: http : //blog.codevader.com/2008/11/02/why-learning-http-does-matter/

这实际上是相反的问题:为什么不在没有数据更改时使用POST。

GET的另一个问题是命令转到浏览器的地址栏。 所以,如果你刷新页面,你再次发出命令,是“删除最后的东西”,“提交订单”或类似的。

比方说,我们有一个网上银行应用程序,我们访问转移页面。 login的用户select将$ 10转移到另一个账户。

点击提交button(作为GET请求)redirect到https://my.bank.com/users/transfer?amount=10&destination=23lk3j2kj31lk2j3k2j

但是互联网连接速度慢,并且/或者服务器很忙,所以在点击提交button后,新页面加载缓慢。

用户感到沮丧,并开始激烈地击中F5(刷新页面)。 猜猜会发生什么? 可能发生多次转账,可能会清空用户的账户。


现在,如果请求是作为POST(或其他任何GET)的第一个F5(刷新页面),用户将使浏览器会轻轻地问:“你确定你想这样做吗?它可以有副作用[bla bla bla ] …“