写点什么

如何选择正确的 HTTP 状态码

  • 2015-12-10
  • 本文字数:1858 字

    阅读完需:约 6 分钟

众所周知,每一个 HTTP 响应都会带有一个状态码,不过对于很多开发者来说,平时使用最多的几个状态码无外乎就是 200、400、404、500 等。那其他众多状态码该应用在何种场景中,什么时候应该使用哪些状态码就成为一个值得我们深入思考的问题了。即便在 Facebook 这样的公司中,那些聪明的开发者所构建的 API 也可能只返回 200。为此, Michael Kropat 专门撰文分析了各个状态码的适用场景,以及我们为何要如此细致地区分不同状态码,同时还谈及了这么做的好处。

有什么是比返回一个 HTTP 状态码还要简单的事情呢?页面渲染了么?如果渲染,那就返回 200 呗。页面不存在?那就是 404。需要将用户重定向到另外一个页面?那就使用 302,也许 301 也行。

一切都是如此简单,不过当有人跟你说,你并没有以 REST 的方式做事情,你可能就要警醒了。新资源是否返回了 RFC 兼容、 Roy-Fielding 建议的状态码?只会是 200 么?也许是 204 No Content、202 Accepted,抑或是 201 Created?

问题在于官方 HTTP/1.1 指南(RFC)最初是在 1997 年发布的。那时的我们还在使用 Netscape Navigator、33.6kbps 的调试解调器网上冲浪呢。这就好比是在现代商业战略中使用孙子兵法一样。这些宝贵的建议并不会随着时间的流逝而发生变化。不过,我们需要真正理解他们。

如果有可视化的决策树就好了,它可以帮助你快速识别与你的情况相吻合的状态码,这样就能忽略掉那些不相关的了。请看下图。

上图看起来是显而易见的,不过我发现很多人都会陷入其中,并且提出诸如“这种情况应该使用 503 Service Unavailable 还是 404 Not Found 呢”?停。如果你在完全不同的响应类别中思考具体的状态码,那就表明你的做法是完全错误的。再来看看上面这张图。

在继续之前我提出几点:

  • 你不必非得听我的,请直接查看 RFC 7231 httpstatuses.com
  • 我所面向的读者是那些创建网站或是使用 REST API 的开发者
  • 我将响应码大致划分为 3 大类

最后再提一点:我其实并没有什么资格就这个主题发表自己的看法,我只不过阅读过一些 RFC 并开发过一些 APIs 而已。如果觉得我说的不对,或是没有使用你倾向于使用的状态码,那么请在文末的评论中指出来,大家一起讨论。

2XX/3XX

4XX

5XX

为何说状态码很重要

虽说 Facebook 中很多聪明的开发者在构建APIs 时只返回200,但我想说的是,状态码确实是非常重要的。现有的状态码对于现代网站/API 来说有些太宽泛了。如果响应要以应用特定的格式来包含一些细节信息,比如说哪些字段验证失败了,原因是什么,这样可以让客户端以更加有意义的方式来处理响应。既然如此,那为何不多花点时间来研究一下那些“不太常用”的HTTP 状态码呢?

在谈及为何说使用具体的状态码是非常重要的时候,人们很爱提到的一个原因就是HTTP 是个分层系统,客户端与服务器之间可能存在着代理、缓存或是其他HTTP 库,如果响应码有意义,那会让这一切都工作地更好。不过,我觉得这个解释站不住脚,比如说未来大家都使用上了HTTPS,我们也禁用掉了所有代理与缓存结点,你能说这时状态码就没用了么?

这里,我想谈谈我认为状态码依然很重要的3 点原因:

1. 客户端可以针对不同的状态码采取不同的行为(或是可以轻松扩展以应对):

  • 301 Moved Permanently 与 302 Found 对于 Google 与其他搜索引擎来说还有 SEO 的隐喻
  • 301 Moved Permanently 有缓存的含义,而 429 Too Many Requests 则没有缓存的含义,诸如此类
  • 客户端库可以通过一段时间的延迟后重试请求来处理 429 Too Many Requests
  • 客户端库可以采取类似的方式处理 503 Service Unavilable

2. 很多状态码所表示的情况可以通过特殊的响应进行处理。

  • 返回 404 而非 405 Method Not Allowed 的 APIs 有时会让我抓狂,“我是输错了 URL 还是使用了错误的 HTTP 方法呢”?
  • 正确区分 502 Bad Gateway 与 500 Internal Server Error 会让你省下不少的调试时间。

3. 不管信不信,目前很多流行的 APIs 建立了一些约定,比如说返回 201 Created、429 Too Many Requests,或是 503 Service Unavilable。如果遵循这些约定,那么用户在使用你的网站 /API 时就会更轻松,遇到问题时也更容易解决。

如果你在使用 HTTP 状态码时遇到了问题,还可以参考如下资源:

各位读者,相信你们中的很多人都曾经或是正在设计 API,那么在这个过程中对于状态码你做过哪些思考呢?有哪些见解呢?欢迎分享出来与 InfoQ 的其他读者一同讨论。

2015-12-10 06:565266
用户头像

发布了 88 篇内容, 共 273.0 次阅读, 收获喜欢 9 次。

关注

评论

发布
暂无评论
发现更多内容

LeetCode 剑指 Offer II 排序 专题总结

爱好编程进阶

Java 程序员 后端开发

不要临时抱佛脚!跳槽面试涨薪全靠它 ,BATJ面试重点

爱好编程进阶

Java 程序员 后端开发

云计算平台与传统平台的区别是什么?怎么理解?

行云管家

云计算 云服务 IDC

Java多线程 高频面试题

爱好编程进阶

Java 程序员 后端开发

php基础语法

爱好编程进阶

Java 程序员 后端开发

Java并发编程—实现线程的方式只有一种

爱好编程进阶

Java 程序员 后端开发

戴尔赋能科创小企业,共塑科创大时代

科创人

重磅推荐-深度学习之ResNet家族

AIWeker

人工智能 深度学习 5月月更 resnet

Redis(十二)

爱好编程进阶

Java 程序员 后端开发

Spring Cloud构建微服务架构(一)服务注册与发现

爱好编程进阶

Java 程序员 后端开发

2022-05微软漏洞通告

火绒安全

微软 终端安全 安全漏洞

多家波卡生态项目招聘开发者,高薪职位等你来 Pick!

One Block Community

区块链 招聘 波卡生态

Maven中的pom

爱好编程进阶

Java 程序员 后端开发

kafka也没那么难--kafka的安装与简单使用

爱好编程进阶

程序员 后端开发

Linux编程之权限系统与工具使用(二)

爱好编程进阶

Java 程序员 后端开发

【Kubernetes】k8s的安全管理详细说明【role赋权和clusterrole赋权详细配置说明

爱好编程进阶

Java 程序员 后端开发

疫情期间,IT运维人员远程办公软件有哪些?

行云管家

远程办公 IT运维 服务器运维 居家办公 运维软件

Java集合源码解析-ConcurrentHashMap(JDK8)

爱好编程进阶

Java 程序员 后端开发

直播可以使用 https 了,快来试试吧

CRMEB

Java实现双向链表的基本操作

爱好编程进阶

程序员 后端开发

Java语言程序设计与数据结构(基础篇)课后练习题 第十三章

爱好编程进阶

Java 程序员 后端开发

linux中route命令超详细用法(十五万字)

爱好编程进阶

Java 程序员 后端开发

MySQL数据库——事务和索引

爱好编程进阶

Java 程序员 后端开发

一道有意思的“初始化”面试题

爱好编程进阶

Java 程序员 后端开发

Java 专项练习【11- 20】

爱好编程进阶

Java 程序员 后端开发

RPC架构设计方法论(完结)

爱好编程进阶

程序员 后端开发

Spring Cloud 学习系列:(八

爱好编程进阶

程序员 后端开发

《深入理解Java虚拟机》读后笔记-运行时数据区域

爱好编程进阶

Java 程序员 后端开发

京东面试题:ElasticSearch深度分页解决方案

爱好编程进阶

Java 程序员 后端开发

龙蜥开源内核追踪利器 Surftrace:协议包解析效率提升 10 倍! | 龙蜥技术

OpenAnolis小助手

Linux 网络协议 系统运维 龙蜥社区 Surftrace

Java程序员面试中最容易答错的8道面试题,你中坑了吗?

爱好编程进阶

程序员 后端开发

如何选择正确的HTTP状态码_REST_张龙_InfoQ精选文章