更新和删除的 HTTP 状态码?

Posted

技术标签:

【中文标题】更新和删除的 HTTP 状态码?【英文标题】:HTTP status code for update and delete? 【发布时间】:2011-01-21 12:06:01 【问题描述】:

我应该为UPDATE (PUT) 和DELETE 设置什么状态码(例如产品成功更新)?

【问题讨论】:

【参考方案1】:

对于 PUT 请求:HTTP 200HTTP 204 应暗示“资源更新成功”。

对于 DELETE 请求:HTTP 200HTTP 204 应暗示“资源已成功删除”。 HTTP 202 也可以返回,这意味着该指令已被服务器接受并且“资源被标记为删除”。

PUT

如果修改了现有资源,则应发送 200(OK)或 204(无内容)响应代码以指示请求成功完成。

DELETE

如果响应包含描述状态的实体,则成功的响应应该是 200(OK),如果尚未执行该操作,则应为 202(已接受),或者如果该操作已执行但响应为 204(无内容)不包括实体。

来源:W3.org: HTTP/1.1 Method Definitions

HTTP 200 OK:成功 HTTP 的标准响应 要求。实际响应将 取决于使用的请求方法。

HTTP 204 No Content:服务器成功处理了请求,但没有返回任何内容

来源:List of HTTP status codes: 2xx Success

【讨论】:

非常有用的帖子!但是我想知道HTTP状态代码应该是什么客户端发送的请求有效(DELETE mySite/entity/123)并且要删除的实体不存在。 @Martin:在这种情况下,服务应该返回 HTTP 404。严格来说,对不存在的资源的 DELETE 或 GET 请求不是“有效”请求 - 即。客户端不应重新尝试该请求,因为它永远不会成功... HTTP 协议定义了 2 类问题 - 具有 4xx 状态代码的问题,客户端必须在重试之前修改请求,以及具有 5xx 状态的问题代码,这表明服务遇到了问题,客户端应该/可以重试相同的确切请求而不更改它。 @JeffMartin 从用户的角度来看可能是这样,但就服务器而言,如果资源不存在,服务器应该返回404。 @Randolpho,幂等性就是要获得相同的结果,无论您调用一次还是多次。客户要求您确保删除该资源。返回 404 有什么好处?为什么它需要知道任何一种方式?现在客户端逻辑必须处理两个单独的响应代码,而不是一个。 @Gili: 或许the wiki会更好解释:方法PUT和DELETE被定义为幂等...注意幂等是指请求完成后系统的状态,因此,虽然服务器采取的操作(例如删除记录)或它返回的响应代码在后续请求中可能会有所不同,但每次的系统状态都是相同的。【参考方案2】:

简答:对于 PUT 和 DELETE,您应该发送 200(OK)或 204(No Content)。

长答案:这是一个完整的决策图(点击放大)。

来源:https://github.com/for-GET/http-decision-diagram

【讨论】:

图表太棒了。有更高分辨率的版本可以打印吗? 在现有资源的 POST 上下文中,另一个 SO 讨论 (***.com/questions/3825990/…) 建议发送 409 Conflict 或 302 Found 而不是附加内容。 我很好奇删除发生后的 204 和 200 响应是否应该颠倒,如果它们是正确的,为什么?删除? -> 响应包括一个实体? -> 是 -> 204 无内容;否 -> 200 OK 图片的更新版本在这里:raw.github.com/for-GET/http-decision-diagram/master/httpdd.png @docksteaderluke 很棒的东西,但为什么没有 POST 代码?【参考方案3】:

这里有一些提示:

删除

200(如果您想在响应中发送一些额外数据)或 204(推荐)。

202 已删除的操作尚未提交。

如果没有什么要删除的,使用204 404(DELETE操作是幂等的,删除一个已经删除的项是操作成功,所以可以返回204,但确实幂等并不一定意味着相同的响应)

其他错误:

400 错误请求(格式错误或错误查询是奇怪但可能的)。 401 未经授权身份验证失败 403 Forbidden:授权失败或无效的应用程序 ID。 405 不允许。当然。 409 资源冲突可能在复杂系统中发生。 还有501502以防出错。

PUT

如果您要更新集合的元素

200/204,原因与上面的 DELETE 相同。 202 如果操作尚未提交。

引用的元素不存在:

PUT 可以是 201(如果您创建了元素,因为那是您的行为)

404如果您不想通过 PUT 创建元素。

400 错误请求(格式错误或错误查询比 DELETE 更常见)。

401 未经授权

403 禁止:身份验证失败或无效的应用程序 ID。

405 不允许。当然。

409 资源冲突可能在复杂系统中发生,例如在 DELETE 中。

422 无法处理的实体它有助于区分“错误请求”(例如格式错误的 XML/JSON)和无效的字段值

还有501502以防出错。

【讨论】:

这个答案几乎完全由两个大引号组成,但没有署名。你是从哪里引用的? 如果状态没有有效更改,204 是否是返回 PUT 请求的正确状态?例如,您要求停用某个用户,但该用户已经处于非活动状态。 PUT请求是幂等的,所以可以返回204,因为系统中的对象发生了变化。 PUT 不是 PATCH,因此您不确定要更改哪个字段。您可以发回 501 - 502,如果您的设计需要知道对象是否与请求中的对象完全相同,但是......我不太喜欢它......我更喜欢204,或者,如果您想停用用户,而不更改更多字段,也许您可​​以使用 PATCH。 我会添加 HTTP 422 不可处理实体。它有助于区分“错误请求”(例如格式错误的 XML/JSON)和无效的字段值。【参考方案4】:

RFC 2616 描述了which status codes to use。

不,它总是 200。

【讨论】:

【参考方案5】:

除了 200 和 204,205 (Reset Content) 可能是有效响应。

服务器已经完成了请求,用户代理应该重置导致请求被发送的文档视图……[例如]清除给出输入的表单。

【讨论】:

【参考方案6】:

这里有一些状态码,你应该知道它的知识。

1XX 信息响应

100 继续 101 交换协议 102 处理 103 早期提示

2XX 成功

200 好的 201 已创建 202 接受 203 非权威信息 204 没有内容 205 重置内容 206 部分内容 207 多状态 208 已举报 226 IM 已使用

3XX 重定向

300 多项选择 301 永久移动 302 找到 303 查看其他 304 未修改 305 使用代理 306 切换代理 307 临时重定向 308 永久重定向

4XX 客户端错误

400 错误请求 401 未经授权 402 需要付款 403 禁止 404 未找到 405 方法不允许 406 不可接受 407 需要代理验证 408 请求超时 409 冲突 410 走了 411 需要长度 412 前提条件失败 413 负载过大 414 URI 太长 415 不支持的媒体类型 416 范围不满足 417 预期失败 418 我是一个茶壶 420 方法失败 421 错误的请求 422 无法处理的实体 423 锁定 424 依赖失败 426 需要升级 428 需要先决条件 429 请求过多 431 请求标头字段太大 451 由于法律原因不可用

5XX 服务器错误

500 内部服务器错误 501 未实施 502 网关错误 503 服务不可用 504 网关超时 505 不支持 Http 版本 506 各种也协商 507 存储空间不足 508 检测到循环 510 未扩展 511 需要网络身份验证

【讨论】:

【参考方案7】:

由于问题涉及 DELETE 是否“应该”返回 200204 值得考虑的是,有些人建议返回一个实体链接,因此首选 200

“而不是返回 204(无内容),API 应该是有用的并且 建议去的地方。在这个例子中,我认为一个明显的链接到 提供是“'somewhere.com/container/'(减去'resource')”- 来自哪个容器 客户端刚刚删除了一个资源。也许客户希望 删除更多资源,这将是一个有用的链接。”

http://blog.ploeh.dk/2013/04/30/rest-lesson-learned-avoid-204-responses/

如果客户端遇到 204 响应,它可以要么放弃,转到 API 的入口点,或者返回到它的上一个资源 参观了。这两个选项都不是特别好。

我个人不会说 204 是错误的(作者也没有;他说“烦人”),因为客户端的良好缓存有很多好处。最好的方式是保持一致。

【讨论】:

【参考方案8】:

2014 年 6 月,RFC7231 已废弃 RFC2616。 如果您通过 HTTP 进行 REST,那么 RFC7231 准确描述了 GET、PUT、POST 和 DELETE 的预期行为

【讨论】:

【参考方案9】:

    "VALIDATON_ERROR": 
        "code": 512,
        "message": "Validation error"
    ,
    "CONTINUE": 
        "code": 100,
        "message": "Continue"
    ,
    "SWITCHING_PROTOCOLS": 
        "code": 101,
        "message": "Switching Protocols"
    ,
    "PROCESSING": 
        "code": 102,
        "message": "Processing"
    ,
    "OK": 
        "code": 200,
        "message": "OK"
    ,
    "CREATED": 
        "code": 201,
        "message": "Created"
    ,
    "ACCEPTED": 
        "code": 202,
        "message": "Accepted"
    ,
    "NON_AUTHORITATIVE_INFORMATION": 
        "code": 203,
        "message": "Non Authoritative Information"
    ,
    "NO_CONTENT": 
        "code": 204,
        "message": "No Content"
    ,
    "RESET_CONTENT": 
        "code": 205,
        "message": "Reset Content"
    ,
    "PARTIAL_CONTENT": 
        "code": 206,
        "message": "Partial Content"
    ,
    "MULTI_STATUS": 
        "code": 207,
        "message": "Multi-Status"
    ,
    "MULTIPLE_CHOICES": 
        "code": 300,
        "message": "Multiple Choices"
    ,
    "MOVED_PERMANENTLY": 
        "code": 301,
        "message": "Moved Permanently"
    ,
    "MOVED_TEMPORARILY": 
        "code": 302,
        "message": "Moved Temporarily"
    ,
    "SEE_OTHER": 
        "code": 303,
        "message": "See Other"
    ,
    "NOT_MODIFIED": 
        "code": 304,
        "message": "Not Modified"
    ,
    "USE_PROXY": 
        "code": 305,
        "message": "Use Proxy"
    ,
    "TEMPORARY_REDIRECT": 
        "code": 307,
        "message": "Temporary Redirect"
    ,
    "PERMANENT_REDIRECT": 
        "code": 308,
        "message": "Permanent Redirect"
    ,
    "BAD_REQUEST": 
        "code": 400,
        "message": "Bad Request"
    ,
    "UNAUTHORIZED": 
        "code": 401,
        "message": "Unauthorized"
    ,
    "PAYMENT_REQUIRED": 
        "code": 402,
        "message": "Payment Required"
    ,
    "FORBIDDEN": 
        "code": 403,
        "message": "Forbidden"
    ,
    "NOT_FOUND": 
        "code": 404,
        "message": "Not Found"
    ,
    "METHOD_NOT_ALLOWED": 
        "code": 405,
        "message": "Method Not Allowed"
    ,
    "NOT_ACCEPTABLE": 
        "code": 406,
        "message": "Not Acceptable"
    ,
    "PROXY_AUTHENTICATION_REQUIRED": 
        "code": 407,
        "message": "Proxy Authentication Required"
    ,
    "REQUEST_TIMEOUT": 
        "code": 408,
        "message": "Request Timeout"
    ,
    "CONFLICT": 
        "code": 409,
        "message": "Conflict"
    ,
    "GONE": 
        "code": 410,
        "message": "Gone"
    ,
    "LENGTH_REQUIRED": 
        "code": 411,
        "message": "Length Required"
    ,
    "PRECONDITION_FAILED": 
        "code": 412,
        "message": "Precondition Failed"
    ,
    "REQUEST_TOO_LONG": 
        "code": 413,
        "message": "Request Entity Too Large"
    ,
    "REQUEST_URI_TOO_LONG": 
        "code": 414,
        "message": "Request-URI Too Long"
    ,
    "UNSUPPORTED_MEDIA_TYPE": 
        "code": 415,
        "message": "Unsupported Media Type"
    ,
    "REQUESTED_RANGE_NOT_SATISFIABLE": 
        "code": 416,
        "message": "Requested Range Not Satisfiable"
    ,
    "EXPECTATION_FAILED": 
        "code": 417,
        "message": "Expectation Failed"
    ,
    "IM_A_TEAPOT": 
        "code": 418,
        "message": "I'm a teapot"
    ,
    "INSUFFICIENT_SPACE_ON_RESOURCE": 
        "code": 419,
        "message": "Insufficient Space on Resource"
    ,
    "METHOD_FAILURE": 
        "code": 420,
        "message": "Method Failure"
    ,
    "UNPROCESSABLE_ENTITY": 
        "code": 422,
        "message": "Unprocessable Entity"
    ,
    "LOCKED": 
        "code": 423,
        "message": "Locked"
    ,
    "FAILED_DEPENDENCY": 
        "code": 424,
        "message": "Failed Dependency"
    ,
    "PRECONDITION_REQUIRED": 
        "code": 428,
        "message": "Precondition Required"
    ,
    "TOO_MANY_REQUESTS": 
        "code": 429,
        "message": "Too Many Requests"
    ,
    "REQUEST_HEADER_FIELDS_TOO_LARGE": 
        "code": 431,
        "message": "Request Header Fields Too"
    ,
    "UNAVAILABLE_FOR_LEGAL_REASONS": 
        "code": 451,
        "message": "Unavailable For Legal Reasons"
    ,
    "INTERNAL_SERVER_ERROR": 
        "code": 500,
        "message": "Internal Server Error"
    ,
    "NOT_IMPLEMENTED": 
        "code": 501,
        "message": "Not Implemented"
    ,
    "BAD_GATEWAY": 
        "code": 502,
        "message": "Bad Gateway"
    ,
    "SERVICE_UNAVAILABLE": 
        "code": 503,
        "message": "Service Unavailable"
    ,
    "GATEWAY_TIMEOUT": 
        "code": 504,
        "message": "Gateway Timeout"
    ,
    "HTTP_VERSION_NOT_SUPPORTED": 
        "code": 505,
        "message": "HTTP Version Not Supported"
    ,
    "INSUFFICIENT_STORAGE": 
        "code": 507,
        "message": "Insufficient Storage"
    ,
    "NETWORK_AUTHENTICATION_REQUIRED": 
        "code": 511,
        "message": "Network Authentication Required"
    

【讨论】:

512 似乎有点偏离,它不是标准化的,我认为验证错误在 4xx 范围内(如 422)。你从哪里得到这份清单的?【参考方案10】:

通常,200 OK201 Created 最适合成功的 PUT 请求。

对于DELETE 方法,202 Accepted204 No Content 将是最佳选择。

【讨论】:

以上是关于更新和删除的 HTTP 状态码?的主要内容,如果未能解决你的问题,请参考以下文章

SEO优化中404错误页面的设置和HTTP状态码说明

spring eureka security 批量更新失败,HTTP 状态码为 401

(已解决):-)(React 和 Django)我无法从我的用户列表中删除用户。 (HTTP 状态码 404)

HTTP状态码

常见的状态码及含义

在实践中区分 HTTP 状态码 403 和 409(或 400)