
文章插图
前两讲中,我们学习了 HTTP 报文里请求行的组成部分,包括请求方法和 URI 。有了请求行,加上后面的头字段就形成了请求头,可以通过 TCP/IP 协议发送给服务器 。
服务器收到请求报文,解析后需要进行处理,具体的业务逻辑多种多样,但最后必定是拼出一个响应报文发回客户端 。
响应报文由响应头加响应体数据组成,响应头又由状态行和头字段构成 。
我们先来复习一下状态行的结构,有三部分:

文章插图
开头的 Version 部分是 HTTP 协议的版本号,通常是 HTTP/1.1,用处不是很大 。
后面的 Reason 部分是原因短语,是状态码的简短文字描述,例如“OK”“Not Found”等等,也可以自定义 。但它只是为了兼容早期的文本客户端而存在,提供的信息很有限,目前的大多数客户端都会忽略它 。
所以,状态行里有用的就只剩下中间的状态码(Status Code)了 。它是一个十进制数字,以代码的形式表示服务器对请求的处理结果,就像我们通常编写程序时函数返回的错误码一样 。
不过你要注意,它的名字是“状态码”而不是“错误码” 。也就是说,它的含义不仅是错误,更重要的意义在于表达 HTTP 数据处理的“状态”,客户端可以依据代码适时转换处理状态,例如继续发送请求、切换协议,重定向跳转等,有那么点 TCP 状态转换的意思 。
状态码目前 RFC 标准里规定的状态码是三位数,所以取值范围就是从 000 到 999 。但如果把代码简单地从 000 开始顺序编下去就显得有点太“low”,不灵活、不利于扩展,所以状态码也被设计成有一定的格式 。
RFC 标准把状态码分成了五类,用数字的第一位表示分类,而 0~99 不用,这样状态码的实际可用范围就大大缩小了,由 000~999 变成了 100~599 。
这五类的具体含义是:
- 1××:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
- 2××:成功,报文已经收到并被正确处理;
- 3××:重定向,资源位置发生变动,需要客户端重新发送请求;
- 4××:客户端错误,请求报文有误,服务器无法处理;
- 5××:服务器错误,服务器在处理请求时内部发生了错误 。
客户端作为请求的发起方,获取响应报文后,需要通过状态码知道请求是否被正确处理,是否要再次发送请求,如果出错了原因又是什么 。这样才能进行下一步的动作,要么发送新请求,要么改正错误重发请求 。
服务器端作为请求的接收方,也应该很好地运用状态码 。在处理请求时,选择最恰当的状态码回复客户端,告知客户端处理的结果,指示客户端下一步应该如何行动 。特别是在出错的时候,尽量不要简单地返 400、500 这样意思含糊不清的状态码 。
目前 RFC 标准里总共有 41 个状态码,但状态码的定义是开放的,允许自行扩展 。所以 Apache、Nginx 等 Web 服务器都定义了一些专有的状态码 。如果你自己开发 Web 应用,也完全可以在不冲突的前提下定义新的代码 。
在我们的实验环境里也可以对这些状态码做测试验证,访问 URI“/12-1”,用查询参数“code=xxx”来检查这些状态码的效果,服务器不仅会在状态行里显示状态码,还会在响应头里用自定义的“Expect-Code”字段输出这个代码 。
例如,在 Chrome 里访问“http://www.chrono.com/12-1?code=405”的结果如下图 。

文章插图
接下来我就挑一些实际开发中比较有价值的状态码逐个详细介绍 。
1××1××类状态码属于提示信息,是协议处理的中间状态,实际能够用到的时候很少 。
我们偶尔能够见到的是“101 Switching Protocols” 。它的意思是客户端使用 Upgrade 头字段,要求在 HTTP 协议的基础上改成其他的协议继续通信,比如 WebSocket 。而如果服务器也同意变更协议,就会发送状态码 101,但这之后的数据传输就不会再使用 HTTP 了 。
2××2××类状态码表示服务器收到并成功处理了客户端的请求,这也是客户端最愿意看到的状态码 。
推荐阅读
- 用netstat查看网络状态详解
- 打印机脱机状态怎么解除
- 深入Facebook 官方React 状态管理器Recoil讲解
- 跑步前如何正确热身?6个动作,激活全身肌肉,提升跑步状态
- 脂肪肝|林心如最新活动照,穿休闲风衣配高马尾,快50岁状态还如此年轻
- 手指头发黑是怎么回事呢?
- 女人动真情后会是什么状态?
- 完美日记|4款网红氨基酸洗面奶,紧致粗大毛孔,让肌肤恢复年轻状态
- 一个接口查询关联了十几张表,响应速度太慢?怎么办?
- 带你彻底掌握 Vue 3.0 的响应式系统
