为什么应该使用 HTTP POST 或 DELETE 而不是 GET 进行删除?

发布于 2024-07-18 03:17:35 字数 648 浏览 19 评论 0原文

我一直在学习 Microsoft 的 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 等方法适用于可能对服务器造成副作用的操作

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

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.

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

Edit

Wikipedia states 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

一桥轻雨一伞开 2024-07-25 03:17:35

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

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

谷歌机器人出现并索引你的页面? 然后会发生什么?

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?

辞慾 2024-07-25 03:17:35

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

来自 HTTP 1.1 RFC 2616

实施者应该意识到
软件代表用户
通过互联网进行互动,以及
应小心允许用户
注意他们可能采取的任何行动
采取这可能会有意想不到的
对自己或他人的重要性。

特别是,该公约已
确定 GET 和 HEAD
方法不应该有
采取其他行动的意义
比检索。 这些方法应该
被认为是“安全的”。 这允许用户
代表其他方法的代理,
例如 POST、PUT 和 DELETE,在
特殊的方式,让用户
意识到一个可能的事实
正在请求采取不安全的行动。

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

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.

From the 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.

童话 2024-07-25 03:17:35

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

对于帖子来说,这不是一个风险。

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".

With posts, this isn't a risk.

安静 2024-07-25 03:17:35

另一个例子..

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

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

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

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

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

希望这是有道理的。

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.

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.

提笔书几行 2024-07-25 03:17:35

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

  • 预取:许多网络浏览器都会使用预取。 意思是
    它会在你之前加载一个页面
    点击链接。 预计到这一点
    稍后您将点击该链接。
  • 机器人:有多个机器人会扫描互联网并为其建立索引
    信息。 他们只会发出 GET
    要求。 你不想删除
    来自 GET 请求的内容
    原因。
  • 缓存: GET HTTP 请求不应更改状态,并且应该是幂等的。 幂等意味着
    发出一次请求,或发出一次
    多次给出相同的结果。
    即没有副作用。 为了
    这就是 GET HTTP 请求的原因
    与缓存紧密相关。
  • HTTP 标准是这么说的:HTTP 标准说明了每个 HTTP 方法是什么
    为了。 建立了几个程序
    使用 HTTP 标准,并且他们假设
    你会按照你现在的方式使用它
    应该。 所以你会有
    一系列未定义的行为
    如果您不遵循,则会出现随机节目。

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.
遮了一弯 2024-07-25 03:17:35

除了蜘蛛和请求必须是幂等之外,获取请求还存在安全问题。 有人可以轻松地向您的用户发送一封包含文本的电子邮件

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

,浏览器将很乐意继续尝试并访问该资源。 使用 POST 并不能解决此类问题(因为您可以很容易地用 javascript 编写表单帖子),但它是一个好的开始。

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

<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.

折戟 2024-07-25 03:17:35

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

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

About this topic (HTTP methods usage), I recommend reading this blog post: 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.

时光磨忆 2024-07-25 03:17:35

除了此处提到的所有出色原因之外,接收服务器还可以记录 GET 请求,例如在 access.log 中。 如果您在请求中发送密码等敏感数据,它们将被记录为明文。

即使它们被散列/加盐以实现安全的数据库存储,漏洞(或有人​​在 IT 人员的背后监视)也可能会泄露它们。 此类数据应放在 POST 正文中。

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.

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.

梦言归人 2024-07-25 03:17:35

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

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

但是互联网连接很慢和/或服务器很忙,因此在点击提交按钮后会显示新页面加载缓慢。

用户感到沮丧并开始疯狂地按 F5(刷新页面)。 猜猜会发生什么? 多次转账可能会导致用户账户清空。


现在,如果请求以 POST(或除 GET 之外的任何其他方式)发出,则第一个 F5(刷新页面)用户将使浏览器轻轻询问“您确定要这样做吗?它可能会产生副作用 [ bla bla bla 】……”

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.

Clicking on the submit button redirects (as a GET request) to 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.


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 ] ... "

紫南 2024-07-25 03:17:35

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文