原文链接:http://racksburg.com/choosing-an-http-status-code/

打开双语对照阅读

有什么能比 HTTP 响应状态码更简单呢?页面渲染了吗?好极了,返回 200。页面不存在?那么是 404。想要跳转到另一个页面?302 或者可能是 301

我喜欢把 HTTP 状态码想象成无线电波传输的 10 码1。“呼叫,呼叫,我是 White Chocolate Thunder,发现 200 OK。”

—— Aaron Patterson (@tenderlove) 2015-10-7

生活是美好的……直到有人告诉你,你还没有做这个 REST2。然后你该失眠了,因为你需了解是否你的新资源返回符合 RFC 规范3,Roy-Fielding 规定的状态码。这里只有 200 吗?或者为什么没有 204 No Content?或许有 202 Accepted……或者有 201 Created

使事情复杂化的是,官方的 HTTP/1.1 指南 —— RFC —— 是写于 1997 年的 在那一年,人们还在使用 Netscape 浏览器以 33.6 KB 的调制解调器来上网。在现在用 HTTP/1.1 就有点像把孙子兵法运用于现代企业战略,兵法无疑是伟大的,但我根本不知道如何具体运用。

能不能有一种直观的决策树来让你快速确定你要用到的少数状态码,并将那些不相关的和废弃的状态码排除掉?

当然可以,现在就能给你一个。

从何说起

它可能看起来很可笑,但是我曾经看到过太多人分不清这些,“这里应该用 503 Service Unavaliable 还是 404 Not Found?”如果你曾经在这上面犹豫,那么你完全弄混了不同的响应类型,你的做法完全是错的。你应该回头看看上面这张流程图。

在深入到具体规范的流程图之前,有一些注意事项:

  • 我建议你阅读 RFC 7231 和 httpstatuses.com
  • 以下内容对开发网站和设计 RESSTish API 有用。
    • 状态码对具体的 web server 实现是完全透明的
    • 当然这里完全忽略代理服务器
  • 我将响应状态码粗略地归为三类:

最后但同样重要的,免责声明:我不保证我写的完全正确,我只是读了一些 RFC 文档在 Racksurg 公司实际工作时,每天用它来实现有用的 API。如果你认为我是错的或者我轻视了你最喜欢的状态码,那可能是我的失误,你可以通过评论告知我究竟错在哪里。

2XX/3XX

4XX

5XX

结语:究竟为什么状态码重要

我并不完全确定它们真的重要。

Facebook 上有许多聪明人,他们创建了 API 只返回 200

反对挑选指定状态码的基本观点是:现有的状态码对于现代网站/API来说太通用了。它无法让客户端以任何一种有意义的方式处理包含特定应用格式的细节的返回信息 —— 例如表单的哪一个字段校验失败了以及为什么失败了。既然如此,那么为什么要在多余的没什么用的 HTTP 状态码上浪费时间?

如果要给出一个理由,来说明为什么使用特定的状态码很重要,公认的理由是 HTTP 是一个分层的系统,如果响应状态码是有特定含义的,任何代理、缓存或者位于客户端和服务器之间的 HTTP 框架能够更好地工作。我不认为这个理由足够更令人信服,尤其现在每个人都开始将服务迁移到 HTTPS,我们禁止了任何不被服务器直接控制的代理或缓存节点。

然而,我会给你三个理由为什么我认为状态码仍然很重要:

  1. 客户端已经处理(或者可以方便地被扩展以便处理)具有特定行为的不同状态码:

    • 相比于 302 Found301 Moved Permanently 在 Google 等搜索引擎上有更好的 SEO 效果。
    • 301 Moved Permanently 能够被缓存,而 429 Too Many Requests 不被缓存等等。 有的客户端库可以处理 428 Too Many Request,将请求回退并一天之后再次尝试请求。 有的客户端可以用同样的方式处理 503 Service Unavilable
  2. 即使对现代需求不能完全满足,许多状态码依然代表着值得处理的特定响应(因此为什么不直接使用标准状态码?)。

    • 那些本该返回 405 Method Not Allowed 却返回 404 的 API 让我疯狂地想,“我是否敲错了 URL 或者我请求用错了 HTTP method?”
    • 我能告诉你如果我们返回 502 Bad Gateway(上游服务问题)而不是返回让人困惑的500 Internal Server Error,那么我们曾经能节省许多调试问题的时间。
  3. 不管你信不信,反正我是信了,在广泛被使用的 API 中正在建立一个约定,以返回状态码例如 201 Created429 Too Many Requests 以及 503 Service Unavialable。如果你遵循这个约定,用户将能更方便地使用你的网站/API并且解决任何他们可能遇到的问题。

在这里面,决定什么时候返回何种状态码是最难的,然而有了正确的知识(别再说我不知道,仔细看前面的流程图),挑选一个有意义的状态码变得简单很多。

说明

别去研究 RFC 2616,更别去研究 RFC 2068,真正有用的是 RFC 7231

参考资料

版权声明

本译文仅用于学习、研究和交流目的,欢迎非商业转载。转载请注明出处、译者和众成翻译的完整链接。要获取包含以上信息的本文Markdown源文本,请点击这里
 

选择一个 HTTP 状态码不再是一件难事 – Racksburg的更多相关文章

  1. 选择一个 HTTP 状态码不再是一件难事 – Racksburg《转载》

    本文转载自:众成翻译 译者:十年踪迹 链接:http://www.zcfy.cc/article/904 原文:http://racksburg.com/choosing-an-http-status ...

  2. 每天一个 HTTP 状态码 前言

    前前言 在重新开始写博文(其实大多也就最多算是日常笔记小结)之际,就想着从短小精悍的文章入手,就想到了 HTTP 状态码.另外,记得很久之前,看过一个<每天一个 Linux 命令>系列文章 ...

  3. 每天一个 HTTP 状态码 203

    203 Non-Authoritative Information 203 Non-Authoritative Information 'Non-Authoritative Informative' ...

  4. 每天一个 HTTP 状态码 201

    201 Created 201 Created 表示客户端的请求已经成功完成,结果是创建了一个新资源,通常用于响应「增删改查」里的「增」.如果是严格按照 RESEful style 的 API,那么当 ...

  5. 每天一个 HTTP 状态码 200

    200 OK 话不多说,这个状态码应该是最最最常用的了,无人不知,无人不晓: 就是表示请求成功的意思,你若安好,便是晴天. 摘自对于 https://www.google.com/ GET 请求的响应 ...

  6. 每天一个 HTTP 状态码 102

    102 Processing 102 Processing 是用于 WebDAV协议 请求的状态码. 这个状态码表示服务器已经收到了客户端的请求,正在处理,但暂时还没有可接触的响应.可以用于防止客户端 ...

  7. 每天一个 HTTP 状态码 205

    205 Reset Content 205 Reset Content 表示服务器成功地处理了客户端的请求,要求客户端重置它发送请求时的文档视图.这个响应码跟 204 No Content 类似,也不 ...

  8. 每天一个 HTTP 状态码 202

    202 Accepted 202 Accepted 表示服务器已经接受了这个请求,但是还不确定这个请求是否能够成功地被处理完.该请求最终可能会或可能不会被执行,并且在处理发生时可能会被拒绝,这是不确定 ...

  9. 每天一个 HTTP 状态码 103

    103 Early Hints 103 Earyly Hints 是被用于在最终 HTTP 消息前返回一些响应头,常和 HTTP Header: Link 一起使用,让客户端在服务器还在准备(当前的这 ...

随机推荐

  1. ViewController 之间设置转场动画

    AddOrEditViewController *addOrEdit = [[AddOrEditViewController alloc] init]; CATransition *transitio ...

  2. CSS3画三角形原理

    1.首先看一下画出一个下三角形完整的代码及效果图 #trangle1-up{ width:; height:; border-left:50px solid transparent; border-r ...

  3. OpenVPN下载、安装、配置及使用详解

    OpenVPN下载.安装.配置及使用详解   OpenVPN简介 OpenVPN是一个用于创建虚拟专用网络(Virtual Private Network)加密通道的免费开源软件.使用OpenVPN可 ...

  4. zepto源码学习-01-整体感知

    在公司一直做移动端的项目,偶尔会做点PC端的东西,但基本上都是和移动端打交道. 移动端嘛必须上zepto,简单介绍下Zepto:它是一个面向高级浏览器的JavaScript框架的,实现JQuery的大 ...

  5. POJ2221+模拟

    参考http://blog.sina.com.cn/s/blog_7de5c6210100tm1h.html 其实是水题............ #include<string.h> #i ...

  6. *[codility]StoneWall

    https://codility.com/demo/take-sample-test/stone_wall 拼石块.用最少的方块.一开始想了想用贪心,是可行的,就是尽量每次把当前的高度往右延伸到最多, ...

  7. [转贴]使用CryptoAPI解析X509证书和P12证书

    原文在 http://bbs.pediy.com/archive/index.php?t-97663.html,但是觉得这篇文章非常好,我抄下来作我笔记用 一.解析X509证书 1.从磁盘上的证书文件 ...

  8. Android笔记5-与USB HID 设备通信(一)

    1.了解 支持USB 主机(host)或者从机(accessary )模式最终是取决于设备的硬件,而与平台版本无关.我们可以通过usesfeature这个方法来查询自己的设备是否支持USB主从.   ...

  9. dojo自定义Widget

    使dojo AMD规范进行widget 定义,开始的时候一直找不到自己定义的widget模块的位置,经过探索,总算有收获,我这个人有毛病,脑子里不允许有一些想不通的问题,一旦有了问题,就非常难受,心里 ...

  10. CreateObject("Wscript.Shell")用法

    WScript.Shell是WshShell对象的ProgID,创建WshShell对象可以运行程序.操作注册表.创建快捷方式.访问系统文件夹.管理环境变量. 该对象有一个run方法. Run 方法创 ...