透视HTTP协议
罗剑锋(Chrono)
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
6077 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词|To Be a HTTP Hero
免费
破冰篇 (7讲)
01 | 时势与英雄:HTTP的前世今生
02 | HTTP是什么?HTTP又不是什么?
03 | HTTP世界全览(上):与HTTP相关的各种概念
04 | HTTP世界全览(下):与HTTP相关的各种协议
05 | 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?
06 | 域名里有哪些门道?
07 | 自己动手,搭建HTTP实验环境
基础篇 (7讲)
08 | 键入网址再按下回车,后面究竟发生了什么?
09 | HTTP报文是什么样子的?
10 | 应该如何理解请求方法?
11 | 你能写出正确的网址吗?
12 | 响应状态码该怎么用?
13 | HTTP有哪些特点?
14 | HTTP有哪些优点?又有哪些缺点?
进阶篇 (8讲)
15 | 海纳百川:HTTP的实体数据
16 | 把大象装进冰箱:HTTP传输大文件的方法
17 | 排队也要讲效率:HTTP的连接管理
18 | 四通八达:HTTP的重定向和跳转
19 | 让我知道你是谁:HTTP的Cookie机制
20 | 生鲜速递:HTTP的缓存控制
21 | 良心中间商:HTTP的代理服务
22 | 冷链周转:HTTP的缓存代理
安全篇 (7讲)
23 | HTTPS是什么?SSL/TLS又是什么?
24 | 固若金汤的根本(上):对称加密与非对称加密
25 | 固若金汤的根本(下):数字签名与证书
26 | 信任始于握手:TLS1.2连接过程解析
27 | 更好更快的握手:TLS1.3特性解析
28 | 连接太慢该怎么办:HTTPS的优化
29 | 我应该迁移到HTTPS吗?
飞翔篇 (4讲)
30 | 时代之风(上):HTTP/2特性概览
31 | 时代之风(下):HTTP/2内核剖析
32 | 未来之路:HTTP/3展望
33 | 我应该迁移到HTTP/2吗?
探索篇 (5讲)
34 | Nginx:高性能的Web服务器
35 | OpenResty:更灵活的Web服务器
36 | WAF:保护我们的网络服务
37 | CDN:加速我们的网络服务
38 | WebSocket:沙盒里的TCP
总结篇 (2讲)
39 | HTTP性能优化面面观(上)
40 | HTTP性能优化面面观(下)
答疑篇 (2讲)
41 | Linux/Mac实验环境搭建与URI查询参数
42 | DHE/ECDHE算法的原理
结束语 (1讲)
结束语 | 做兴趣使然的Hero
透视HTTP协议
登录|注册

12 | 响应状态码该怎么用?

Chrono 2019-06-24
前两讲中,我们学习了 HTTP 报文里请求行的组成部分,包括请求方法和 URI。有了请求行,加上后面的头字段就形成了请求头,可以通过 TCP/IP 协议发送给服务器。
服务器收到请求报文,解析后需要进行处理,具体的业务逻辑多种多样,但最后必定是拼出一个响应报文发回客户端。
响应报文由响应头加响应体数据组成,响应头又由状态行和头字段构成。
我们先来复习一下状态行的结构,有三部分:
开头的 Version 部分是 HTTP 协议的版本号,通常是 HTTP/1.1,用处不是很大。
后面的 Reason 部分是原因短语,是状态码的简短文字描述,例如“OK”“Not Found”等等,也可以自定义。但它只是为了兼容早期的文本客户端而存在,提供的信息很有限,目前的大多数客户端都会忽略它。
所以,状态行里有用的就只剩下中间的状态码(Status Code)了。它是一个十进制数字,以代码的形式表示服务器对请求的处理结果,就像我们通常编写程序时函数返回的错误码一样。
不过你要注意,它的名字是“状态码”而不是“错误码”。也就是说,它的含义不仅是错误,更重要的意义在于表达 HTTP 数据处理的“状态”,客户端可以依据代码适时转换处理状态,例如继续发送请求、切换协议,重定向跳转等,有那么点 TCP 状态转换的意思。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《透视HTTP协议》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(25)

  • 肥low
    1、4xx一般是服务端业务状态码,看业务上怎么解决的,5xx就比较多了,500、502比如是在lnmp架构下,500是php代码写的很烂,导致nginx的upstream接受错误,抛异常了。502就是php-fpm挂了。504说明有慢查询php-fpm可能还在运行着,可是ngx由于本身的超时设置已经主动断开了,entity too large就是上传发文件超过ngx本身设置,其它的好像还没遇到过,404大多是浏览器请求facon.ico导致的,现在前后端分离根本没这个东西

    2、参数错误一般是通过接口返回具体的业务代码来表明,http响应报文一般都是200,也有400的,但是我的经验中一般是返回的body为json格式,然后里面通过一个errno来标识一下,具体怎么规定我觉得在接口文档中写清楚就好

    作者回复: 写的很好。

    2019-06-25
    5
  • 第一个问题: 目前客户端基本都是解析成失败的情况,大部分给个失败错误友好界面
     
    第二个问题: 目前服务器很多也是返回4xx的错误妈,感觉被烂用了,应该要返回5xx,然后我们还会定义一个msg字段,用来说明具体失败的原因

    作者回复: √

    2019-06-24
    3
  • 壹笙☞漂泊
    课后题:
    1、给个错误页面、或者弹窗报个错误,然后做跳转
    2、在返回body里面写明错误原因,状态码一般给500

    总结:
    1、状态行结构:
    version【SP】status code【SP】reason【CRLF】
    version:是HTTP协议的版本号,用处不大
    reason:是原因短语,简短的文字描述,如果“OK”“Not Found”等等,也可以自定义,用处也不大,很多客户端会忽略,为了兼容早期的文本客户端
    status code:状态码,不是错误码,表达状态。以代码的形式表示服务器对请求的处理结果。
    2、状态码
    RFC标准规定状态码是三位数,把状态码分成了五类,用数字的第一位表示分类。
    * 1xx:提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
    * 2xx: 成功,报文已经收到并被正确处理;
    * 3xx:重定向,资源位置发生变动,需要客户端重新发送请求;
    * 4xx:客户端错误,请求报文有误,服务器无法处理;
    * 5xx:服务器错误,服务器在处理请求时内部发生了错误。

    作者回复: 总结的不错。

    2019-06-25
    2
  • 马哲富
    希望老师在后续的过程中讲一下206这个断点续传,是不是类似于百度网盘那种下载软件暂停后再继续下载也是类似的原理?

    作者回复: 后面会专门讲的。

    2019-06-24
    2
  • 许童童
    1: 收到了一个非标准的状态码,一般约定返回message字段,然后弹窗提示
    2: 用406状态码
    2019-06-24
    2
  • 彧豪
    1.一般接口报错的话返回的body中都会封装有错误消息,显示消息即可,401一般都不作处理,比如获取登录用户的信息的接口,未登录的时候调是401,是因为没有带相应token过去,登录之后就能正常返回登录用户的信息了,自己处理的情况比如SPA,用户访问了一个不存在的路由,此时前端自己返回一个404的页面,里面是一张图片:“么么哒,网页找不到了耶”之类的🤣🤣,5xx这个时候需要找服务端沟通了,正式上线一般不会出现5xx的错误,一般在开发时出现
    2.返回的body中告知前端错误信息
    另外就是老师貌似忘了讲401了,401也挺常见/用的,默认原因短语是"Unauthorized",比如调登录接口没带授权的时候

    作者回复: 401在rfc7235中,我用的比较少,所以就不说了。

    感谢你的补充。

    2019-06-24
    2
  • 风翱
    对于问题二,如果缺少的参数,服务端采用友好的方式提示。 调试方面确实方便了,但是对于安全性呢?

    作者回复: 这里应该不涉及安全的问题,如果比较在意,可以约定用一些代码来表示。

    2019-06-24
    1
    1
  • 我行我素
    1.4**一般都是弹窗提示,将错误显示出来,5**有单独的页面显示错误信息;
    2.在自己的项目中都是返回json直接明确告诉缺少什么参数

    作者回复: √

    2019-06-24
    1
  • 无名
    问题一:4xx,5xx,跳转到单独页面提示。
    问题二:我们一般交互的都说json格式,会内部再定义一个code和msg,然后定义一个参数错误code,在msg中提示错误具体原因。

    作者回复: 不错。

    2019-06-24
    1
  • 听雨
    这些状态码是怎么出现的呢,自己代码中也没有设置呀,怎么自动就有了呢。重定向,怎么就知道资源位置发生变化,并且返回状态码的。我用redirect测试,只有200,也没有3xx呀

    作者回复:
    1.有的状态码是底层应用自动完善的,比如如果不设置就自动是200。

    2.重定向是服务器开发者自己知道资源有变化,手动设置的。比如网站临时维护,就重定向到维护页面。

    3.重定向必定是3xx代码,可以在Chrome开发者工具里看,比如在实验环境里。你用的可能是php吧,可以看一下函数手册,看它是怎么运作的。

    2019-11-05
  • 星极
    弱弱问句,最后2个问题中的http客户端和服务器分别指的是类似HttpClient和Nginx,还是业务开发时http接口的请求方和服务方?个人比较严谨,老师看到了麻烦回复下

    作者回复: 我认为是第二种理解。

    2019-10-28
  • 齐庆福
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status/100

    作者回复: 100状态码用的很少,我个人不太推荐使用。

    2019-10-27
  • 蓝白条纹
    第二个问题,看到有人说4××.也有人说返回5××代码,老师你都说是对的。描述是响应头缺少参数,像这种格式上正确,服务端实际处理时发现的缺少参数,到底是算客户端的错误还是算服务端的呢?

    作者回复: 因为http很灵活,所以对于同一个问题会有多个解法,不存在唯一的答案。

    所以对于这样的错误,可以根据自己的实际情况来处理,如果严格要求客户端,那么就返回4xx,认为是客户端错误。如果严格要求服务器,那么就认为缺少必须的数据无法处理,返回5xx。

    2019-10-21
  • Demon.Lee
    开发过程中遇到了一个response.code是201,查询了下表示:请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,且其URI已经随Location头信息返回。假如需要的资源无法及时创建的话,应当返回'202 Accepted'。

    作者回复: 2xx代码在课程里没有全列出来,只讲了几个最常用的。因为http很灵活,所以返回码要求的也不是很严格,可以在头字段、body里再返回更多的信息。

    2019-10-11
  • qiezitx
    1、跳转到一个统一的页面/弹窗。当然也要根据业务需求,pm说的算。。。
    2、请求有误,属于4xx。看看已知状态码中有没有定义,没有的话自定义一个。ps,看到有同学回答,返回200或500,然后在body去定义,的确很多怎么搞的,可能是怕到时候自定义多了400的区间不够,拿出来另找区间更清楚吧。

    作者回复:
    1.对

    2.是的,所以很多时候都是返回一个json,里面自由定义错误信息。

    2019-09-25
  • 渴望做梦
    老师,如果客户端的请求参数有问题,无法识别,这时候服务端该如何返回呢?

    作者回复: 可以返回一个4xx错误,然后在body里用json等格式说明具体的错误原因。

    其他的同学已经回答了,可以参考。

    2019-08-21
  • Geek_steven_wang
    4xx错误时,要尽量详细清晰,告知客户端请求错在那。如果预定义不够,就自己扩展。
    5xx,不用太详细,为了安全,只告诉那部分出错,方便定位。
    501 Not Implemented”表示客户端请求的功能还不支持,和“即将开业,敬请期待”的意思差不多,不过具体什么时候“开业”就不好说了。

    “502 Bad Gateway”通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。

    “503 Service Unavailable”表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。

    如请求少了query字段,自定义一个错误码440 ,文字描述中 说明缺少那个参数。

    作者回复: good。

    2019-08-14
  • ly
    个人对状态码使用的理解:
    就目前项目开发的过程中,状态码的使用对业务程序来说,基本上很少去利用,大致都是nginx、tomcat、spring等这些框架、中间件会返回一些状态码,例如接口不存在,框架会返回404,nginx配置有问题或者拒绝访问返回403或者502等状态码,一旦正确进入业务接口的时候,不管请求的用户id是否在用户库中存在、以及请求参数中是否缺少必要参数,都是返回200状态码,只是在body的json里面会返回自己特有的业务错误码,例如: {"code":-1,"message:"userid参数必须填写"}。
    整体来讲,开发业务的程序员很少会去思考该返回什么http状态码,不知道这样的开发过程是否标准?

    作者回复: 这也是web服务里的一种常见做法。

    因为http状态码很有限,而且含义不是很清楚,所以通常需要在body里返回额外的数据来说明更详细的错误原因,常用的就是json了。

    2019-08-11
  • Mr.Chen
    老师好,http://www.chrono.com/12-1?code=405 , 服务器怎么知道”code“是状态码关键字呢,或者说服务器上确实有地方管理参数关键字呢。谢谢。

    作者回复: 是在服务器端写l服务程序,具体在实验环境里就是lua脚本,可以看一下lua目录里对应的脚本文件,很容易理解。

    2019-08-08
  • 四月的紫色花
    1.你在开发 HTTP 客户端,收到了一个非标准的状态码,比如 4××、5××,应当如何应对呢?
    客户端给个提示,类似于现在的404 Not Found那样
    2.你在开发 HTTP 服务器,处理请求时发现报文里缺了一个必需的 query 参数,应该如何告知客户端错误原因呢?
    返回一个4××类的错误码。另外想请教老师,query参数上节课我们讲说是资源属性,那为何还会有必需的时候呢,客户端人家不需要指定属性,直接就返回这个资源就好了呀。如果说必需,那我的理解是说,在客户端请求的路径下,有很多它要的资源,这些资源属性不大相同,所以服务器不知道需要返回哪个,所以必需查询参数,这样理解可否正确😂

    作者回复: 1/2问题已经有同学回答的比较好了,可以参考。

    可以用query参数来描述资源的属性,获取更精确的资源,比如图片可以指定大小、格式,js可以指定版本号。

    资源也可以不用query参数描述,不是必须的,如何使用在于服务器端如何定义资源。

    2019-08-07
收起评论
25
返回
顶部