为什么我们除了HTTP GET,PUT和POST之外还需要什么呢?

时间:2020-03-06 14:51:26  来源:igfitidea点击:

使用HTTP GET,PUT,DELETE,POST,HEAD的实际好处是什么?为什么不关注他们的行为益处(安全性和幂等性),忘记他们的名字,并根据我们想要的行为使用GET,PUT或者POST?

为什么我们不应该只使用GET,PUT和POST(并删除HEAD,DELETE)?

解决方案

[REST] [1]方法使用POST,GET,PUT和DELETE来实现Web资源的CRUD规则。这是将对象暴露给Web请求的一种简单整洁的方法。它是没有开销的Web服务。

只是为了澄清语义上的差异。每个操作都大不相同。关键是要具有清晰,独特含义的漂亮HTTP方法。

POST创建新对象。 URI没有密钥。它接受定义该对象的消息正文。 SQL插入。 [编辑尽管POST没有任何技术原因没有技术要求,但是REST人士强烈建议POST具有CREATE的独特含义,它不应该具有密钥。]

GET检索现有对象。 URI可能有一个密钥,这取决于我们正在执行单例GET还是列出GET。 SQL选择

PUT更新现有对象。 URI有一个密钥。它接受更新对象的消息正文。 SQL更新。

DELETE删除现有对象。 URI有一个密钥。 SQL删除。

我们可以使用POST而不是PUT更新记录吗?并非没有引起歧义。动词应具有明确的作用。此外,POST URI没有密钥,而PUT必须具有密钥。

发布时,我希望创建201. 如果我不明白,那是不对的。同样,当我输入时,我希望200 OK。如果我不明白,那是不对的。

我想我们可能会坚持在POST执行POST或者PUT的某些歧义。 URI必须不同。关联的消息也可能不同。通常,REST人员会从SQL中获得提示,而INSERT和UPDATE是不同的动词。

我们可以假设如果该记录不存在,则应插入UPDATE;如果该记录存​​在,则应进行更新。但是,如果UPDATE表示UPDATE而更新失败则意味着出现问题,则更为简单。对INSERT的秘密回退使操作变得模棱两可。

如果我们不构建RESTful接口,则通常仅使用GET和POST进行检索和创建/更新。当用户单击表单上的"提交"时,通常会有URI差异或者消息内容差异来区分POST和PUT。但是,它不是很干净,因为代码必须确定我们是处于POST = create情况还是POST = update情况。

为什么我们需要的比POST还多?它允许数据双向流动,那么为什么需要GET?答案与问题基本相同。通过标准化各种方法的基本期望,其他过程可以更好地知道该怎么做。

例如,介入缓存代理可以有更好的机会做正确的事情。

例如考虑一下HEAD。如果代理服务器知道HEAD的含义,那么它可以处理来自先前GET请求的结果,以提供对HEAD请求的正确答案。它可以知道POST,PUT和DELETE不应该被缓存。

并非所有托管服务商都不支持PUT,DELETE。

我问了这个问题,在理想的世界中,我们会拥有所有动词,但是....:

RESTful Web服务和HTTP动词

为了限制歧义,可以更好/更轻松地重用我们的简单REST API。

我们只能使用GET和POST,但随后就会失去PUT和DELETE带来的一些准确性和清晰度。 POST是通配符操作,可能有任何含义。
PUT和DELETE的行为非常明确。
如果我们想到了资源管理API,那么GET,PUT和DELETE可能覆盖所需功能的80%-90%。如果我们将自己限制为GET和POST,则使用错误指定的POST访问40%-60%的api。

早期的Web服务器大战可能是造成这种情况的原因。

在1996年编写的HTTP 1.0中,只有GET,HEAD和POST。但是,如我们在附录D中所见,供应商开始添加自己的东西。因此,为了保持HTTP兼容,他们不得不在1999年制作HTTP 1.1.

However, HTTP/1.0 does    not sufficiently take into consideration
  the effects of hierarchical proxies, caching, the need for
  persistent connections, or virtual hosts. In addition, the proliferation
  of incompletely-implemented  applications calling themselves
  "HTTP/1.0" has necessitated a protocol version change in order for
  two communicating applications to determine each other's true capabilities.
  
  This specification defines the protocol referred to as "HTTP/1.1". This protocol includes more stringent requirements than HTTP/1.0 in    order
  to ensure reliable implementation of its features.

使用GET和POST的Web应用程序允许用户创建,查看,修改和删除其数据,但是可以在最初为这些目的而创建的HTTP命令之上的一层上进行操作。 REST背后的想法之一是回归Web设计的原始意图,其中每个CRUD动词都有特定的HTTP操作。

同样,HEAD命令可用于改善(可能很大)文件下载的用户体验。我们调用HEAD找出响应的大小,然后调用GET实际检索内容。

有关说明性示例,请参见以下链接。它还提出了使用OPTIONS http方法的一种方法,此处尚未讨论。

GET,PUT,DELETE和POST是大二学生认为可以将网页简化为一些统一原则的时代的产物。

如今,大多数网页都是复合实体,其中包含部分或者全部这些原始操作。例如,页面可能具有用于查看或者更新客户信息的表单,这些表单可能跨越多个表。

我通常在php中使用$ _REQUEST [],而不是真正在乎信息如何到达。我会选择基于效率使用GET或者PUT方法,而不是基础(多个)范式。

POST无法保证安全性或者幂等性。这是PUT和DELETE都是幂等的原因(即1 + N个相同的请求具有与1个请求相同的最终结果)。

PUT用于在给定URI处设置资源的状态。当我们向特定URI处的资源发送POST请求时,该资源不应被内容替换。最多应将其添加。这就是为什么在添加POST的情况下POST不具有幂等性的原因,每个请求都会添加到资源中(例如,每次将新消息发布到讨论论坛)。

DELETE用于确保将给定URI中的资源从服务器中删除。 POST通常不应用于删除,除非提交删除请求。同样,在这种情况下,我们要发布到的资源的URI不应是我们要删除的资源的URI。 POST所针对的任何资源都是一种接受POST数据以追加到自身,添加到集合或者以其他方式进行处理的资源。

如果我们只关心GET请求的标头并且不想在实际内容上浪费带宽,则使用HEAD。真高兴。

没有人发布我一直在寻找的答案,因此我将尝试自己总结要点。

" RESTful Web服务"第8章"重载POST"部分中写道:"如果我们完全不想使用PUT和DELETE,则它完全是RESTful的,可以通过GET公开对资源的安全操作,而所有其他操作都可以通过重载POST进行。这样做违反了我的观点。面向资源的体系结构,但符合REST的限制性较小的规则。"

简而言之,将PUT / DELETE替换为POST会使API更加难以阅读,并且PUT / DELETE调用不再是幂等的。

有些HTTP扩展名(例如WebDAV)需要其他功能。

http://en.wikipedia.org/wiki/WebDAV

一句话:

幂等

再说几句话:

GET =安全+幂等

PUT =幂等

删除=等幂

POST =安全或者幂等

"幂等"只是意味着我们可以一遍又一遍地进行操作,并且始终会做完全相同的事情。

我们可以根据需要多次发出PUT(更新)或者DELETE请求,并且每次都会产生相同的效果,但是所需的效果会修改资源,因此不被视为"安全"。

POST请求应该为每个请求创建一个新资源,这意味着效果每次都会有所不同。因此,POST不被认为是安全的或者幂等的。

诸如GET和HEAD之类的方法只是读取操作,因此被认为是"安全"的以及幂等的。

这实际上是一个非常重要的概念,因为它提供了一种标准/一致的方式来解释HTTP事务。这在安全环境中特别有用。

HEAD对于确定给定服务器的时钟设置(准确到1秒或者网络往返时间之内,以较大者为准)非常有用。从Slashdot获取Futurama报价也很棒:

~$ curl -I slashdot.org
HTTP/1.1 200 OK
Date: Wed, 29 Oct 2008 05:35:13 GMT
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001227
X-Fry: That's a chick show. I prefer programs of the genre: World's Blankiest Blank.
Cache-Control: private
Pragma: private
Connection: close
Content-Type: text/html; charset=iso-8859-1

对于cURL,`-I'是执行HEAD请求的选项。要获取给定服务器的当前日期和时间,只需执行

curl -I $ server | grep ^ Date