V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
xiaqinglin
V2EX  ›  问与答

HTTP PUT 和 POST 的区别?

  •  
  •   xiaqinglin · 2017-04-25 14:00:56 +08:00 · 6601 次点击
    这是一个创建于 2550 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在在写一个 restful 接口,想问下大神么 HTTP 方法里 PUT 和 POST 的区别,我看了一些文章提到“幂等”的概念,即“ PUT 方法是幂等的。幂等的方法意味着请求成功执行所得到的的结果不依赖于该方法被执行的次数。”,但是还是不太能理解?

    还有我写 restful 接口的时候,做更新操作的时候是不是只要实现 put 或者 post 中的一个就可以了?不需要两个一起实现?
    24 条回复    2018-11-09 09:53:27 +08:00
    learnshare
        1
    learnshare  
       2017-04-25 14:09:10 +08:00
    分不清楚 PUT 和 POST ,你怎么知道是在写 RESTful ?

    PUT 一般用于更改已有数据, POST 一般用来创建新数据
    zhangchioulin
        2
    zhangchioulin  
       2017-04-25 14:12:43 +08:00 via Android
    为什么不看下 V2EX 的发帖规范?
    xiaqinglin
        3
    xiaqinglin  
    OP
       2017-04-25 14:13:01 +08:00
    @learnshare 我知道大概的区别,但是 PUT 其实也可以用来创建新数据,就是想搞清楚它们的本质区别嘛,第一次写 restful 接口还是个菜鸟
    lovejoy
        4
    lovejoy  
       2017-04-25 14:27:03 +08:00   ❤️ 1
    put 是原子的
    whalegia
        5
    whalegia  
       2017-04-25 14:39:16 +08:00
    PUT 也不一定不用来创建新数据吧。

    比如说你有一个 API ,实现返回 user id 功能。如果这个客户端给的 user id 存在,就返回这个已知 id ,不存在,则创建新 id 返回。这个就可以用 PUT
    whalegia
        6
    whalegia  
       2017-04-25 14:43:25 +08:00
    其实我想搭车问一下,把一个 HttpResponseMessage 转化成 IHttpActionResult ,用了 “ http://stackoverflow.com/questions/21758615/why-should-i-use-ihttpactionresult-instead-of-httpresponsemessage ”帖子里第一个回答的方法,不过 HttpRespnseMessage 中除了状态码还包含了一个 json object ,为什么转换成 IHttpActionResult 后 content 就为 null 了?

    直接返回 this.content(HttpStatusCode, jsonObject) 是可行的,但是我想加一些自定义的头部。
    下午查了一下午,没搞明白。。。
    xiaqinglin
        7
    xiaqinglin  
    OP
       2017-04-25 14:49:17 +08:00
    @whalegia 为什么感觉这个操作 GET 也可以做,我混乱了。。。
    whalegia
        8
    whalegia  
       2017-04-25 14:51:08 +08:00
    @xiaqinglin 前一段还有帖子争论说只要 GET 和 DELETE 什么都能做了呢。

    但是楼主问的 RESTful 风格嘛。
    whalegia
        9
    whalegia  
       2017-04-25 14:59:20 +08:00
    哦 sorry 你就是楼主。。。
    或者这么说吧
    对 POST 来说,创建一个新用户,创建成功,应该返回 201 ;如果用户已经存在,则应该返回 409 conflict
    对 PUT 来说,创建成功,返回 201 ;用户已经存在,返回 200 或者 202 。但是除开状态码,返回给客户端的内容应该是一样的,都是客户端请求的 user id 为定值的用户数据,所谓“幂等”?
    kiwi95
        10
    kiwi95  
       2017-04-25 14:59:32 +08:00 via Android
    @xiaqinglin 做当然可以做,任何操作都可以用一个 get 去做,但 restful 了就要看动作的语义嘛
    bianhua
        11
    bianhua  
       2017-04-25 15:03:09 +08:00
    其实只要搞清 CURD 的区别就行了:
    C(POST), U(PUT), R(GET), D(DELETE)

    POST 用来创建数据,如果一个数据已经存在(而又不能自行创建新的 Key (比如自增 ID )来代表它(比如 User ID )),则应该返回 409 ,否则 200 。
    PUT 用来修改已有数据,如果一条数据还不存在,应该返回 404 ,否则 200 。
    xiaqinglin
        12
    xiaqinglin  
    OP
       2017-04-25 15:13:53 +08:00
    @bianhua @whalegia 感谢两位,大概明白了
    hst001
        13
    hst001  
       2017-04-25 15:25:51 +08:00
    在这里要拉 `PATCH` 来一起说说:
    POST - create
    PUT - replace
    PATCH - update
    learnshare
        14
    learnshare  
       2017-04-25 15:56:25 +08:00
    @xiaqinglin 的确一个 GET 可以干任何事情,但缺少语义
    就像所有 API 都可以走同一个 URL ,看起来很整齐,但不那么好理解
    zhujinliang
        15
    zhujinliang  
       2017-04-25 16:13:55 +08:00
    幂等就是说,如果你提交的参数是相同的,不论提交几次,结果都是一样的,或者可以理解,最终结果都以最后一次提交为准
    比如你修改 id=1 的 user 的 name 为 'zhu',无论你请求多少次, name 都是 zhu
    不幂等的情况,比如你创建一个 name 为 'zhu' 的用户,第一次请求,系统里有了一个 zhu ,返回 id 为 1 ,再请求一次,系统里又多了一个 zhu ,返回 id 为 2 ,系统状态以及返回结果与请求次数有关
    otakustay
        16
    otakustay  
       2017-04-25 16:31:17 +08:00
    PUT 的 URL 必须指向**唯一**的资源, POST 的 URL 可以指向**资源的集合**,所以 PUT 无论调用几次一定是把这个**唯一**的资源更新成请求提供的内容,所以幂等
    Cbdy
        17
    Cbdy  
       2017-04-25 17:01:29 +08:00
    post 是简单 http 请求, put 不是,跨源的时候浏览器和服务器的策略不一样
    yuedingwangji
        18
    yuedingwangji  
       2017-04-26 12:43:49 +08:00
    小白一个 , 记得 put 的请求字数是有限制的, 好像有 2048 还是多少, post 没限制
    xiaqinglin
        19
    xiaqinglin  
    OP
       2017-04-26 13:47:52 +08:00
    @Cbdy 不是啊, PUT 和 POST 都是 HTTP1.1 里面的请求方法
    lygmqkl
        20
    lygmqkl  
       2017-04-26 15:15:23 +08:00
    POST 是非幂等,每次 POST 都会增加一个 record
    PUT 是幂等 且完全替换,每次 PUT 都会对指定的 record 进行更新
    PATCH 是非幂等,每次 PATCH 都只会对部分数据进行更新,并且可能出现++的情况。

    只关注到 POST and PUT 等于才入门,真正重要的是 PATCH and OPTION
    zivsu
        21
    zivsu  
       2017-04-27 10:00:58 +08:00
    Use PUT when you can update a resource completely through a specific resource. For instance, if you know that an article resides at http://example.org/article/1234, you can PUT a new resource representation of this article directly through a PUT on this URL.

    If you do not know the actual resource location, for instance, when you add a new article, but do not have any idea where to store it, you can POST it to an URL, and let the server decide the actual URL.
    mingyun
        22
    mingyun  
       2017-04-29 11:53:15 +08:00
    @zhujinliang 解释到位
    chengs
        23
    chengs  
       2018-01-10 01:51:12 +08:00
    PUT 原意是指定路经 post 文件
    fundebug
        24
    fundebug  
       2018-11-09 09:53:27 +08:00
    幂等即 idempoten

    > Methods can also have the property of “ idempotence ” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

    意思就是执行多次结果是一样的。

    PUT 是 idempotent 的方法,而 POST 不是。

    https://blog.fundebug.com/2018/11/09/http-method-put-vs-post/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5693 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:18 · PVG 10:18 · LAX 19:18 · JFK 22:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.