POST和PUT HTTP REQUEST有什么区别?

它们似乎都在向身体内部的服务器发送数据,那么是什么让它们不同呢?

882396 次浏览

PUT是一种将内容“上传到”特定URI或覆盖该URI中已经存在的内容的方法。

另一方面,POST是一种提交与给定URI相关的数据的方式。

参考HTTP RFC

只有语义学。

HTTPPUT应该接受请求的主体,然后将其存储在URI标识的资源中。

HTTPPOST更通用。它应该在服务器上启动一个操作。该操作可以是将请求正文存储在URI标识的资源处,也可以是不同的URI,也可以是不同的操作。

PUT是喜欢文件上传。对URI的放置正好影响该URI。对URI的POST可能有任何影响。

POST被认为是工厂类型的方法。您可以在其中包含数据以创建您想要的内容,而另一端的任何内容都知道如何处理它。PUT用于更新给定URL的存量数据,或者在您知道URI将是什么并且它还不存在时创建新内容(与POST相反,POST会创建一些内容并在必要时返回一个URL)。

HTTP PUT:

PUT将文件或资源放在特定的URI上,并且正好在该URI上。如果该URI上已经有文件或资源,PUT将替换该文件或资源。如果那里没有文件或资源,PUT会创建一个。PUT是幂等,但矛盾的是PUT响应不可缓存。

HTTP 1.1 RFC位置的PUT

HTTP POST:

POST将数据发送到特定的URI,并期望该URI上的资源处理请求。此时Web服务器可以确定如何处理指定资源上下文中的数据。POST方法不是幂等,但是POST响应可缓存,只要服务器设置适当的Cache-Control和Expires标头。

官方HTTP RFC将POST指定为:

  • 现有资源的注释;
  • 将消息发布到公告板、新闻组、邮件列表,或类似的文章;
  • 提供一个数据块,例如提交数据的结果表单,到数据处理过程;
  • 通过追加操作扩展数据库。

HTTP 1.1 POST的RFC位置

POST和PUT的区别:

RFC本身解释了核心区别:

的基本区别POST和PUT请求反映在的不同含义请求URI。POST请求中的URI识别将处理封闭的实体。那资源可能是一个数据接受过程,通往其他一些的门户协议,或单独的实体接受注释。相反,PUT请求中的URI标识请求所附实体----用户代理知道URI是什么意图和服务器不得尝试将请求应用于某些其他资源。如果服务器希望该请求适用于不同的URI,它必须发送301(移动永久)响应;然后用户代理可以#36825;决定是否重定向请求。

此外,更简洁地说,RFC 7231第4.3.4节PUT状态(强调添加),

4.3.4.把

PUT方法请求目标资源的状态为createdreplaced,状态由表示定义包含在请求消息有效负载中。

使用正确的方法,无关的除外:

RESTROA与SOAP的一个好处是,当使用HTTP REST ROA时,它鼓励正确使用HTTP动词/方法。因此,例如,只有当您想在该确切位置创建资源时,您才会使用PUT。你永远不会使用GET来创建或修改资源。

举个REST样式资源的例子:

POST /books包含一堆图书信息可能会创建一本新书,并使用标识该书的新URL进行响应:/books/5

PUT /books/5必须创建ID为5的新书,或者将现有书替换为ID 5。

在非资源风格中,POST几乎可以用于任何有副作用的东西。另一个区别是PUT应该是幂等的:相同数据到相同URL的多个PUT应该没问题,而多个POST可能会创建多个对象或您的POST操作所做的任何事情。

其他人已经发布了很好的答案,我只是想补充一点,对于大多数语言、框架和用例,您将比PUT更频繁地处理POST。到PUT, DELETE,等基本上是琐事问题的地步。

据我所知,PUT主要用于更新记录。

  1. POST-创建文档或任何其他资源

  2. PUT-更新创建的文档或任何其他资源。

但要明确的是,PUT通常会“替换”现有记录,如果它在那里,如果它不在那里,则会创建。

请看:http://zacharyvoase.com/2009/07/03/http-post-put-diff/

我最近对Web开发人员的一个流行误解感到非常恼火,即POST用于创建资源,PUT用于更新/更改资源。

如果您查看RFC 2616的第55页(“超文本传输协议-HTTP/1.1”),第9.6节(“PUT”),您将看到PUT的实际用途:

PUT方法请求将封闭的实体存储在提供的Request est-URI下。

还有一个方便的段落来解释POST和PUT之间的区别:

POST和PUT请求之间的根本区别体现在请求URI的不同含义上。POST请求中的URI标识了将处理封闭实体的资源。该资源可能是数据接受进程、其他协议的网关或接受注释的单独实体。相比之下,PUT请求中的URI标识了请求封闭的实体——用户代理知道想要什么URI,服务器不得尝试将请求应用于其他资源。

它没有提到更新和创建之间的任何区别,因为这不是它的目的。而是关于这两者之间的区别:

obj.set_attribute(value) # A POST request.

还有这个:

obj.attribute = value # A PUT request.

所以,请停止这种流行误解的传播。阅读你的RFC。

定义HTTP方法的操作

HTTP协议定义了许多为请求分配语义含义的方法。大多数RESTful Web API使用的常见HTTP方法是:

get检索指定URI处资源的表示形式。响应消息的正文包含请求资源的详细信息。

POST在指定的URI处创建新资源。请求消息的主体提供了新资源的详细信息。请注意,POST也可用于触发实际上没有创建资源的操作。

在指定的URI处创建或替换资源。请求消息的主体指定要创建或更新的资源。

补丁执行资源的部分更新。请求主体指定要应用于资源的更改集。

删除删除指定URI处的资源。

特定请求的效果应该取决于资源是集合还是单个项目。下表总结了使用电子商务示例的大多数RESTful实现采用的常见约定。并非所有这些请求都可以实现——这取决于特定场景。

资源库POSTget删除
/customers创建一个新客户找回所有客户客户批量更新删除所有客户
/customers/1错误为客户1检索详细信息更新客户1的详细信息(如果存在)删除客户1
/customers/1/orders为客户1创建新订单获取客户1的所有订单批量更新客户1的订单删除客户1的所有订单

POST、PUT和PATCH之间的区别可能令人困惑。

POST请求创建资源。服务器为新资源分配URI并将该URI返回给客户端。在REST model中,您经常将POST请求应用于集合。新资源被添加到集合中。POST请求也可用于将数据提交给现有资源进行处理,而无需创建任何新资源。

请求创建资源或更新现有资源。客户端指定资源的URI。请求正文包含资源的完整表示。如果具有此URI的资源已经存在,则将其替换。否则,如果服务器支持,则创建新资源。PUT请求最常应用于单个项目的资源,例如特定客户,而不是集合。服务器可能支持更新,但不支持通过PUT创建。是否支持通过PUT创建取决于客户端是否可以在资源存在之前将URI有意义地分配给资源。如果不是,那么使用POST创建资源,使用PUT or PATCH更新。

补丁请求对现有资源执行部分更新。客户端指定资源的URI。请求主体指定一组要应用于资源的更改。这比使用PUT更有效,因为客户端只发送更改,而不是资源的整个表示。如果服务器支持,从技术上讲,PATCH也可以创建一个新资源(通过指定一组对“空”资源的更新)。

PUT请求必须是幂等的。如果客户端多次提交相同的PUT请求,结果应该始终相同(相同的资源将被修改为相同的值)。POST and PATCH请求不能保证是幂等的。

  1. get:从服务器检索数据。应该没有其他效果。
  2. :用请求负载替换目标资源。可用于更新或创建新资源。
  3. 补丁:类似于PUT,但仅用于更新现有资源中的某些字段。
  4. POST:对有效负载执行特定于资源的处理。可用于不同的操作,包括创建新资源、上传文件或提交Web表单。
  5. 删除:从服务器中删除数据。
  6. 跟踪:提供一种测试服务器接收到什么的方法。它只是返回发送的内容。
  7. 选项:允许客户端获取有关服务支持的请求方法的信息。相关的响应标头是允许支持的方法。也在CORS中用作飞行前请求,以通知服务器实际的请求方法并询问自定义标头。
  8. HEAD:仅返回响应标头。
  9. CONNECT:当浏览器知道它与代理对话并且最终URI以https://开头时使用。CONNECT的目的是允许端到端加密的TLS会话,因此代理无法读取数据。

POST和PUT的区别在于PUT是幂等的,这意味着多次调用同一个PUT请求总是会产生相同的结果(即没有副作用),而另一方面,重复调用POST请求可能会产生(额外的)副作用,即多次创建相同的资源。

GET:使用GET的请求仅检索数据,即请求指定资源的表示

POST:它将数据发送到服务器以创建资源。请求主体的类型由Content-Type标头指示。它通常会导致服务器状态的变化或副作用

PUT:创建一个新资源或将目标资源的表示替换为请求有效负载

PATCH:用于对资源应用部分修改

DELETE:删除指定的资源

TRACE:它沿着目标资源的路径执行消息环回测试,提供有用的调试机制

OPTIONS:它用于描述目标资源的通信选项,客户端可以为OPTIONS方法指定URL,或者指定星号(*)来引用整个服务器。

HEAD:它要求与GET请求相同的响应,但没有响应主体

CONNECT:它建立一个隧道到目标资源标识的服务器,可用于访问使用SSL(HTTPS)的网站

值得一提的是,POST受制于一些常见的跨站点请求伪造(CSRF)攻击,而PUT则不然。

当受害者访问attackersite.com时,下面的CSRF是不可能#0

攻击的影响受害者无意中删除了用户只是因为它(受害者)在访问attackersite.com之前在target.site.com上以admin登录:

attackersite.com上的恶意代码:

案例1:正常请求。保存的target.site.com cookie将由浏览器自动发送:(注意:仅在端点支持PUT更安全,因为它不是受支持的<form>属性值)

<!--deletes user with id 5--><form id="myform" method="post" action="http://target.site.com/deleteUser" ><input type="hidden" name="userId" value="5"></form><script>document.createElement('form').submit.call(document.getElementById('myform'));</script>

保存的target.site.com cookie将由浏览器自动发送:(注意:在端点仅支持PUT更安全,因为尝试发送PUT将触发飞行前请求,其响应将阻止浏览器请求deleteUser页面)

//deletes user with id 5var xhr = new XMLHttpRequest();xhr.open("POST", "http://target.site.com/deleteUser");xhr.withCredentials=true;xhr.send(["userId=5"]);

MDNRef:[…]与“简单请求”不同(上面讨论过), --[[ 手段:POST/GET/HEAD ]]--, 对于“预加载”请求,浏览器首先使用OPTIONS方法发送HTTP请求[…]

cors在行动:[…]某些类型的请求,例如DELETE或PUT,需要更进一步,在发出实际请求之前请求服务器的权限[…],即所谓的飞行前请求[…]

REST-ful用法

POST用于创建新资源,然后返回资源URI

EXREQUEST : POST ..../books{"book":"booName","author":"authorName"}

此调用可能会创建一本新书并返回该书URI

Response ...THE-NEW-RESOURCE-URI/books/5

PUT用于替换资源,如果该资源存在,则只需更新它,但如果该资源不存在,则创建它。

REQUEST : PUT ..../books/5{"book":"booName","author":"authorName"}

对于PUT,我们知道资源标识符,但POST将返回新的资源标识符

非REST-ful使用

POST用于在服务器端发起一个动作,这个动作可能会也可能不会创建一个资源,但是这个动作总是会产生副作用,它会改变服务器上的一些东西

PUT用于在特定URL处放置或替换文字内容

REST-ful和非REST-ful风格的另一个区别

POST是非幂等操作:如果使用相同的请求多次执行,它会导致一些更改。

PUT是幂等操作:如果使用相同的请求多次执行,它将没有副作用。

实际上除了它们的标题之外没有任何区别。GET和其他方法之间实际上有一个基本的区别。使用“GET”-Request方法,您在url地址行中发送数据,它们首先由问号分隔,然后用&符号分隔。

但是使用“POST”请求方法,您不能通过url传递数据,但您必须将数据作为请求“body”中的对象传递。在服务器端,您必须读出接收到的内容的主体以获取发送的数据。但是另一方面,当您发送“GET”-Request时,无法在主体中发送内容。

那种认为GET只是用来获取数据,POST是用来发布数据的说法是完全错误的。没有人能阻止你根据GET请求或POST请求发送的数据在后端创建新内容、删除现有内容、编辑现有内容或做任何事情。没有人能阻止你对后端进行编码,即通过POST请求,客户端会请求一些数据。

对于请求,无论你使用哪种方法,你都调用一个URL并发送或不发送一些数据来指定你想传递给服务器以处理你的请求的信息,然后客户端从服务器获得答案。数据可以包含你想发送的任何信息,后端可以对数据做任何它想做的事情,响应可以包含你想放在那里的任何信息。

只有这两种基本方法。GET和POST。但这是它们的结构,这使它们不同,而不是你在后端编码的内容。在后端,你可以使用接收到的数据编写任何你想要的代码。但是使用“POST”请求,你必须在主体中而不是在url地址行中发送/检索数据,并且使用“GET”请求,你必须在url地址行而不是主体中发送/检索数据。仅此而已。

所有其他方法,如“PUT”、“DELETE”等,它们的结构与“POST”相同。

POST方法主要用于,如果您想在某种程度上隐藏内容,因为无论您在url-addressline中写入什么,都会保存在缓存中,而GET-方法与使用数据写入url-addressline相同。因此,如果您想发送敏感数据,不一定总是用户名和密码,但例如一些ID或哈希,您不希望在url-address-line中显示,那么您应该使用POST方法。

此外,URL地址行的长度限制为1024个符号,而“POST”方法不受限制。因此,如果您有更多的数据,您可能无法将其与GET-Request一起发送,但您需要使用POST-Request。所以这也是POST请求的另一个优点。

但是当您没有复杂的文本要发送时,处理GET请求要容易得多。否则,这是POST方法的另一个优点,是,使用GET方法,您需要对文本进行url编码,以便能够在文本甚至空格内发送一些符号。但是使用POST方法,您没有任何限制,您的内容不需要以任何方式更改或操作。

PUT和POST都是REST方法。

PUT-如果我们两次使用相同的参数使用PUT发出相同的请求,第二个请求将没有任何效果。这就是PUT通常用于更新场景的原因,使用相同的参数多次调用Update不会比初始调用做任何事情,因此PUT是幂等的。

POST不是幂等的,例如创建将在目标中创建两个单独的条目,因此它不是幂等的,因此CREATE在POST中被广泛使用。

每次使用具有相同参数的POST进行相同的调用将导致发生两件不同的事情,因此POST通常用于创建场景

何时使用一个或另一个应该非常简单,但复杂的措辞对我们许多人来说是混淆的根源。

何时使用它们:

  • 当您想修改已经是资源集合一部分的单一资源时,请使用PUTPUT完全替换资源。示例:PUT /resources/:resourceId

    附注:如果要更新资源的一部分,请使用PATCH


  • 如果要在资源集合下添加子资源,请使用POST
    示例:POST => /resources

一般而言:

  • 通常,在实践中,总是使用PUT进行更新操作。
  • 始终使用POST进行创建操作。

示例:

GET /company/reports=>获取所有报告
GET /company/reports/{id}=>获取以"id"标识的举报信息
POST /company/reports=>创建一个新报告
PUT /company/reports/{id}=>更新“id”标识的举报信息
PATCH /company/reports/{id}=>更新举报信息中“id”标识的部分信息
DELETE /company/reports/{id}=>按“id”删除报告

简单地说,你可以说:

1.HTTP获取:用于获取一个或多个项目

2.HTTP:用于创建项目

3.HTTP:用于更新项目

4.HTTP补丁:用于部分更新项目

5.HTTP删除:用于删除项目

摘要

  • 使用 PUT创建或替换 目标资源的状态,使用请求中包含的表示所定义的状态。标准化的预期效果是 无能为力,因此它通知中间人,在通信失败的情况下,他们可以重复请求。
  • 否则使用 POST(包括创建或替换目标资源以外的资源的状态)。它的预期效果是 没有标准化,因此中间体不能依赖于任何通用性质。

参考文献

POSTPUT请求方法之间语义差异的最新权威描述在 RFC 7231中给出(Roy Fielding,Julian Reschke,2014) :

封闭表示的不同意图突出了 POSTPUT方法之间的根本区别。POST请求中的目标资源旨在根据资源自身的语义处理封闭的表示,而 PUT请求中的封闭表示被定义为替换目标资源的状态。因此,PUT的意图是幂等的,并且对中介是可见的,即使确切的效果只有原始服务器知道。

换句话说,PUT的预期效果是 POST0(用请求中包含的表示所定义的状态创建或替换 POST1资源的状态) ,因此对所有目标资源都是通用的,而 POST的预期效果是 POST2,因此是特定于每个目标资源的。因此,POST可以用于任何事情,包括实现 PUT和其他请求方法(GETHEADDELETECONNECTOPTIONSTRACE)的预期效果。

但建议在适用时始终使用更专业的请求方法而不是 POST,因为它为中间信息检索提供了更多的信息以实现自动化(因为 GETHEADOPTIONSTRACE被定义为 GET3) ,处理通信故障(因为 GETHEADPUTDELETEOPTIONSTRACE被定义为 GET4) ,以及优化缓存性能(因为 GETHEAD被定义为 GET5) ,如 GET6(Roy Fielding,2009)所解释的:

POST只有在其他方法非常适合的情况下才会出现问题: 例如,检索应该是某种资源的表示(GET)的信息,完全替换表示(PUT) ,或者其他标准化方法,这些方法告诉中间人一些比“这可能会改变某些东西”更有价值的东西其他方法对于中介来说更有价值,因为它们讲述了如何自动处理故障以及中间缓存如何优化其行为。POST没有这些特征,但这并不意味着我们可以没有它。POST在 HTTP 中有许多有用的用途,包括“此操作不值得标准化”的一般用途

张贴和存放主要用于数据的张贴和其他更新数据。但是您可以只对 post request 进行同样的操作。