它们似乎都在向身体内部的服务器发送数据,那么它们有什么不同呢?
当前回答
只有语义。
HTTP PUT应该接受请求体,然后将其存储在由URI标识的资源中。
HTTP POST更为通用。它应该在服务器上发起一个操作。该操作可以是将请求体存储在由URI标识的资源中,也可以是不同的URI,也可以是不同的操作。
PUT类似于文件上传。对URI的put操作恰好影响该URI。对URI的POST可以产生任何效果。
其他回答
其他人已经发布了很好的答案,我只是想补充一点,在大多数语言、框架和用例中,你会更多地使用POST,而不是PUT。PUT、DELETE等基本都是鸡毛蒜毛的问题。
值得一提的是,POST容易受到一些常见的跨站请求伪造(CSRF)攻击,而PUT则不会。
当受害者访问attackersite.com时,下面的CSRF是不可能的。
攻击的效果是,受害者无意中删除一个用户,只是因为它(受害者)在访问attackersite.com之前以admin身份登录target.site.com:
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>
案例2:XHR请求。保存的target.site.com cookie将被浏览器自动发送:(注意:只支持PUT,在端点,是更安全的,因为尝试发送PUT将触发一个preflight请求,其响应将阻止浏览器请求deleteUser页面)
//deletes user with id 5
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://target.site.com/deleteUser");
xhr.withCredentials=true;
xhr.send(["userId=5"]);
MDN Ref: [..]与“简单请求”(上面讨论过)不同,——[[意思是:POST/GET/HEAD]]——,对于“预飞行”请求,浏览器首先使用OPTIONS方法发送一个HTTP请求[..]
Cors在行动:[..]某些类型的请求,如DELETE或PUT,在发出实际请求之前需要进一步请求服务器的许可。]所谓的飞行前请求[..]
根据HTTP方法定义操作
HTTP协议定义了许多为请求分配语义的方法。大多数RESTful web api使用的常见HTTP方法有:
GET在指定URI处检索资源的表示形式。响应消息的主体包含所请求资源的详细信息。
POST在指定的URI上创建一个新资源。请求消息的主体提供了新资源的详细信息。注意,POST还可以用于触发不实际创建资源的操作。
PUT在指定的URI上创建或替换资源。请求消息的主体指定要创建或更新的资源。
PATCH执行资源的部分更新。请求体指定要应用于资源的更改集。
DELETE删除指定URI上的资源。
特定请求的效果应取决于资源是集合还是单个项。下表通过电子商务示例总结了大多数RESTful实现采用的常见约定。并不是所有这些请求都可以实现——这取决于具体的场景。
Resource | POST | GET | PUT | DELETE |
---|---|---|---|---|
/customers | Create a new customer | Retrieve all customers | Bulk update of customers | Remove all customers |
/customers/1 | Error | Retrieve the details for customer 1 | Update the details of customer 1 if it exists | Remove customer 1 |
/customers/1/orders | Create a new order for customer 1 | Retrieve all orders for customer 1 | Bulk update of orders for customer 1 | Remove all orders for customer 1 |
POST、PUT和PATCH之间的区别可能令人困惑。
POST请求创建一个资源。服务器为新资源分配URI,并将该URI返回给客户端。在REST模型中,您经常对集合应用POST请求。新资源被添加到集合中。POST请求还可以用于将数据提交到现有资源进行处理,而不需要创建任何新资源。
A PUT request creates a resource or updates an existing resource. The client specifies the URI for the resource. The request body contains a complete representation of the resource. If a resource with this URI already exists, it is replaced. Otherwise, a new resource is created, if the server supports doing so. PUT requests are most frequently applied to resources that are individual items, such as a specific customer, rather than collections. A server might support updates but not creation via PUT. Whether to support creation via PUT depends on whether the client can meaningfully assign a URI to a resource before it exists. If not, then use POST to create resources and PUT or PATCH to update.
PATCH请求对现有资源执行部分更新。客户端为资源指定URI。请求体指定要应用于资源的一组更改。这可能比使用PUT更有效,因为客户端只发送更改,而不是资源的整个表示。从技术上讲,如果服务器支持的话,PATCH还可以创建一个新资源(通过指定一组对“null”资源的更新)。
PUT请求必须是等幂的。如果客户端多次提交相同的PUT请求,结果应该总是相同的(相同的资源将被修改为相同的值)。POST和PATCH请求不能保证是等幂的。
REST-ful用法
POST用于创建一个新资源,然后返回资源URI
EX
REQUEST : 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将返回新的资源标识符
无剩余用途
POST用于在服务器端发起一个操作,这个操作可能会创建资源,也可能不会创建资源,但是这个操作会有副作用,它总是会改变服务器上的一些东西
PUT用于放置或替换特定URL上的文字内容
REST-ful和non - rest风格的另一个区别
POST是非幂等操作:如果对同一个请求执行多次,将导致一些变化。
PUT是幂等操作:如果对同一个请求执行多次,它将没有副作用。
POST和PUT之间的区别在于PUT是幂等的,这意味着多次调用相同的PUT请求总是会产生相同的结果(没有副作用),而另一方面,重复调用POST请求可能会产生多次创建相同资源的(额外的)副作用。
GET:使用GET的请求只检索数据,也就是说它请求指定资源的表示
POST:向服务器发送数据以创建资源。请求体的类型由Content-Type报头表示。它通常会导致服务器的状态变化或副作用
PUT:创建一个新资源或用请求有效负载替换目标资源的表示
PATCH:用于对资源应用部分修改
DELETE:删除指定资源
TRACE:它沿着通往目标资源的路径执行消息循环测试,提供了一种有用的调试机制
OPTIONS:用于描述目标资源的通信选项,客户端可以为OPTIONS方法指定一个URL,或者一个星号(*)来引用整个服务器。
HEAD:它请求与GET请求相同的响应,但没有响应体
CONNECT:它建立到目标资源标识的服务器的隧道,可用于访问使用SSL (HTTPS)的网站
推荐文章
- 什么是HTTP“主机”报头?
- 哪个HTTP状态代码表示“尚未准备好,稍后再试”?
- 如何阻止恶意代码欺骗“Origin”报头来利用CORS?
- 为什么说“HTTP是无状态协议”?
- 我需要HTTP GET请求的内容类型报头吗?
- 如何让Chrome允许混合内容?
- 正确的方式删除cookies服务器端
- REST DELETE真的是幂等的吗?
- 了解Chrome网络日志“停滞”状态
- jQuery发布JSON
- 用户代理字符串可以有多大?
- 什么是接受* HTTP报头q=0.5 ?
- HTTP状态码200(缓存)和状态码304之间有什么区别?
- HTTP POST返回错误:417“期望失败。”
- 什么是HTTP中的“406-不可接受的响应”?