asp.net-mvc 为什么应该使用 HTTP POST 或 DELETE 而不是 GET 来删除?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/786070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:32:08  来源:igfitidea点击:

Why should you delete using an HTTP POST or DELETE, rather than GET?

asp.net-mvchttphttp-delete

提问by Richard Ev

I have been working through Microsoft's ASP.NET MVC tutorials, ending up at this page

我一直在研究 Microsoft 的 ASP.NET MVC 教程,最后在此页面

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

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

The following statement is made towards the bottom of this page:

本页底部有以下声明:

In general, you don't want to perform an HTTP GET operation when invoking an action that modifies the state of your web application. When performing a delete, you want to perform an HTTP POST, or better yet, an HTTP DELETE operation.

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

Is this true? Can anyone offer a more detailed explanation for the rationale behind this statement?

这是真的?任何人都可以对这一声明背后的理由提供更详细的解释吗?

Edit

编辑

Wikipediastates the following:

维基百科声明如下:

Some methods (for example, HEAD, GET, OPTIONS and TRACE) are defined as safe, which means they are intended only for information retrieval and should not change the state of the server.

By contrast, methods such as POST, PUT and DELETE are intended for actions which may cause side effects either on the server

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

相比之下,诸如 POST、PUT 和 DELETE 之类的方法用于可能对服务器造成副作用的操作

回答by Chris Cudmore

Jon Skeet's answer is the canonical answer. But: Suppose you have a link:

乔恩斯基特的答案是规范的答案。但是:假设您有一个链接:

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

and the google-bot comes along and indexes your page? What happens then?

然后 google-bot 出现并索引您的页面?那会发生什么?

回答by Jon Skeet

GET is conventionally free of side-effects - in other words, it doesn't change the state. That means the results can be cached, bookmarks can be made safely etc.

GET 通常没有副作用——换句话说,它不会改变状态。这意味着可以缓存结果,可以安全地制作书签等。

From the HTTP 1.1 RFC 2616

来自HTTP 1.1 RFC 2616

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

实施者应该意识到软件在他们通过 Internet 的交互中代表用户,并且应该小心让用户意识到他们可能采取的任何可能对他们自己或他人具有意外意义的行为。

特别是,约定已经建立,GET 和 HEAD 方法不应该具有采取除检索以外的动作的意义。这些方法应该被认为是“安全的”。这允许用户代理以特殊方式表示其他方法,例如 POST、PUT 和 DELETE,以便用户知道正在请求可能不安全的操作这一事实。

自然,不可能确保服务器不会因为执行 GET 请求而产生副作用;事实上,一些动态资源认为这是一个特性。这里的重要区别是用户没有要求副作用,因此不能对它们负责。

回答by Marc Gravell

Apart from purist issues around being idempotent, there is a practical side: spiders/bots/crawlers etc will follow hyperlinks. If you have your "delete" action as a hyperlink that does a GET, then google can merrily delete all your data. See "The Spider of Doom".

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

With posts, this isn't a risk.

对于帖子,这不是风险。

回答by Neil

Another example..

另一个例子..

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

This will delete the article if you are logged in and have the right privileges. If your site accepts comments for example and a user submits that link as an image; like so:

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

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

Then when you yourself as the admin user come to browse through the comments on your site the browser will attempt to fetch that image by sending off a request to that URL. But because you are logged in whilst the browser is doing this the article will get deleted.

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

You may not even notice, without looking at the source code as most browsers wont show anything if it can't find an image.

如果不查看源代码,您甚至可能不会注意到,因为如果找不到图像,大多数浏览器将不会显示任何内容。

Hope that makes sense.

希望这是有道理的。

回答by Brian R. Bondy

Please see my answer here. It applies equally to this question.

请在此处查看我的回答。它同样适用于这个问题。

  • Prefetch:A lot of web browsers will use prefetching. Which means that it will load a page before you click on the link. Anticipating that you will click on that link later.
  • Bots:There are several bots that scan and index the internet for information. They will only issue GET requests. You don't want to delete something from a GET request for this reason.
  • Caching:GET HTTP requests are not supposed to change state and they should be idempotent. Idempotent means that issuing a request once, or issuing it multiple times gives the same result. I.e. there are no side effects. For this reason GET HTTP requests are tightly tied to caching.
  • HTTP standard says so: The HTTP standard says what each HTTP method is for. Several programs are built to use the HTTP standard, and they assume that you will use it the way you are supposed to. So you will have undefined behavior from a slew of random programs if you don't follow.
  • 预取:很多网络浏览器都会使用预取。这意味着它会在您单击链接之前加载页面。预计您稍后会单击该链接。
  • 机器人:有几个机器人可以扫描和索引互联网以获取信息。他们只会发出 GET 请求。由于这个原因,您不想从 GET 请求中删除某些内容。
  • 缓存:GET HTTP 请求不应该改变状态,它们应该是幂等的。幂等意味着发出一次请求或多次发出请求会产生相同的结果。即没有副作用。因此,GET HTTP 请求与缓存紧密相关。
  • HTTP 标准是这样说的: HTTP 标准说明了每个 HTTP 方法的用途。有几个程序是为使用 HTTP 标准而构建的,它们假定您将按照预期的方式使用它。因此,如果您不遵循,您将会从大量随机程序中获得未定义的行为。

回答by John Foster

In addition to spiders and requests having to be idempotent there's also a security issue with get requests. Someone can easily send your users an e-mail with

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

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

in the text and the browser will happily go along and try and access the resource. Using POST isn't a cure for such things (as you can put together a form post in javascript pretty easily) but it's a good start.

在文本中,浏览器会很乐意继续尝试访问资源。使用 POST 并不能解决这些问题(因为您可以很容易地在 javascript 中组合一个表单帖子),但这是一个好的开始。

回答by razenha

About this topic (HTTP methods usage), I recommend reading this blog post: http://blog.codevader.com/2008/11/02/why-learning-http-does-matter/

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

This is actually the opposite problem: why do not use POST when no data is changed.

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

回答by Andrei R?nea

Let's say we have an internet banking application and we visit the transfer page. The logged in user chooses to transfer $10 to another account.

假设我们有一个网上银行应用程序,我们访问了转账页面。登录用户选择将 10 美元转移到另一个帐户。

Clicking on the submit button redirects (as a GET request) to https://my.bank.com/users/transfer?amount=10&destination=23lk3j2kj31lk2j3k2j

单击提交按钮重定向(作为 GET 请求)到https://my.bank.com/users/transfer?amount=10&destination=23lk3j2kj31lk2j3k2j

But the internet connection is slow and/or the server(s) is(are) busy so after hitting the submit button the new page is loading slow.

但是互联网连接很慢和/或服务器很忙,所以在点击提交按钮后,新页面的加载速度很慢。

The user gets frustrated and starts hitting F5 (refresh page) furiously. Guess what will happen? More than one transfer will occur possibly emptying the user's account.

用户感到沮丧并开始疯狂地按 F5(刷新页面)。猜猜会发生什么?将发生不止一次转移,可能会清空用户的帐户。



Now if the request is made as POST (or anything else than GET) the first F5 (refresh page) the user will make the browser will gently ask "are you sure you want to do that? It can have side effects [ bla bla bla ] ... "

现在,如果请求是作为 POST(或 GET 以外的任何东西)发出的第一个 F5(刷新页面),用户将使浏览器轻轻地询问“你确定要这样做吗?它可能有副作用 [bla bla bla ] ...”

回答by Siddhartha

Apart from all the excellent reasons mentioned on here, GET requests could be logged by the recipient server, such as in the access.log. If you send across sensitive data such as passwords in the request, they'll get logged as plaintext.

除了这里提到的所有极好的原因之外,接收服务器可能会记录 GET 请求,例如在access.log. 如果您在请求中发送密码等敏感数据,它们将被记录为纯文本。

Even if they are hashed/salted for secure DB storage, a breach (or someone looking over the IT guy's shoulder) could reveal them. Such data should go in the POST body.

即使为了安全的数据库存储对它们进行了散列/加盐处理,漏洞(或有人​​从 IT 人员的肩膀上查看)也可能会发现它们。这些数据应该放在 POST 正文中。

回答by PhiLho

Another issue with GET is that the command goes to the browser's address bar. So if you refresh the page, you issue the command again, be it "delete last stuff", "submit the order" or similar.

GET 的另一个问题是命令会转到浏览器的地址栏。因此,如果您刷新页面,则再次发出命令,无论是“删除最后的内容”、“提交订单”还是类似的。