HTTP码是200,响应体的code是500,什么鬼?

前言

有人突然问了我这么一个问题,说后端传过来的数据,HTTP状态码(以下简称HTTP码)是200,响应体的code是500,这种操作怎么理解?到底是200还是500?

HTTP码是200
响应体返回code是500

我本以为,这叫啥问题,结果。。憋了半天我竟一时不知道怎么回答。。

今天彻底搞清楚!

RESTful

RESTful是想尽办法利用现有的HTTP协议的各个“成员”,比如Method就把PUT、PATCH、DELETE这种方法都用上了,那么HTTP码这么好用的东西是一定是要用的。而且,RESTful根本就不允许你在响应体里写{code: 200}这种鬼。

项目现状

回到项目现状中,在请求体里写{code: 200}几乎成了某些人眼里的业界规范了啊!HTTP码无脑200啊!这咋解释?!

其实很好解释,这就是半瓶子咣当的程序员对于HTTP码理解错误,前端对后端说一句:“你要给我返回状态码啊”,后端就屁颠屁颠的把码放到请求体里了,前端看到后,心想:“又不是不能用,算了,反正绝大多数情况下都是200”。所以,到今天,搞得这成了业界标准一样。而且一些框架本身就使用HTTP码200、code 500来报错。

从业界来说,

结果成了:

  1. 脑子比较清醒的程序员,用HTTP码表达状态,用axios拦截器对各种HTTP码做了处理。

  2. 脑子不清醒的程序员,用code表达状态,axios拦截这个code,当然,最后肯定能跑通。但是,这显然是不规范的。

常用状态码都有什么?

建议不要超出这几个,这几个足够用。

200请求成功
201创建成功 专门用于创建新的记录的时候
301永久重定向 网址永久变更成另外一个网址
302临时重定向 网址临时变更成另外一个网址
400无效的请求 请求的网址无效等
401没有登录 需要登录才能访问
403没有权限 虽然登陆了,但是没有权限
404请求资源不存在 请求的东西不存在,比如某个人的信息
500服务器端错误 服务器端发生了错误

业界大公司,谁在用{code: 200}

一个不存在的公司,FaceBook,就在用{code: 200}。谷歌等公司在用状态码200。再比如现在有个流行的java+vue后台系统,若依,官方演示的code我们看一下,它不是{code: 200}

image.png

HTTP码不是200的话,能返回响应体么?

当然能,包括HTTP 404错误,都能返回你想要的JSON格式的响应体。

只在HTTP码写,前端能精准捕获吗?

这个问题才是核心关键!

你在HTTP码写的飞起,但前端捕获不了,不也是白扯么?

我们测一下:

原生Fetch

成功时:

image.png

服务器返回404时:

image.png

跨域,但目标服务器无效时:

image.png

jQuery

这种方法是可以精确捕获各个错误代码的:

$.ajax({
  dataType: "json",
  url: 'goodsList.json',
  statusCode: {
    200: function(err) {
      console.log(err);
    },
    404: function(err) {
      console.log(err);
    }
  },
});

成功时:返回JSON本身。

404出错时:

image.png

axios

利用响应拦截器拦截一下:

axios.interceptors.response.use(
  function (response) {// 对响应数据做点什么
    return response;
  },
  function (err) {
    console.log(err.response);
  }
);

成功时:

image.png

404出错时,err.response打印:

image.png

结论

市面上主流的ajax库和原生Fetch都支持捕获404,而且都是存放在response.status。其他的HTTP码也都是一样的道理,就不多说了。

所以,有什么理由不使用HTTP码呢??

HTTP码到底怎么定?

  1. 成功的状态码一定是200,就行了。

  2. 关于失败的状态码,我专门说一下,其实并没有什么一定之规,只要保证:如果使用常见的HTTP状态码,一定要符合通常理解的规范;如果使用了自定义的状态码,比如1000以上的状态码,那就团队自己定就好了,定了就要遵守,别经常变来变去。

  3. msg只是在弹窗里显示,不要拿msg当做出错的判定依据,必须只拿HTTP码当做依据。

最后一个问题,响应体应该怎么写?

先说GET的响应体

{
    msg: null,
    rows: [...],
    total: 14
  }
  1. 不要写code,不要写code,不要写code!

  2. msg在200前提下就null,因为成功前提下没有必要弹窗提示,除非极少数场合真的需要弹窗提示,不在200前提下可以写明到底什么出了错。msg的内容就是给中国用户看的可阅读的提示,会由前端组件放到提示框里,因此,绝对不要写“success”或者“err”这种鬼!!

  3. rows也可以叫list,强调的是数组解构,空数组则返回[]。不是数组的话,也可以叫result,result可以是基本类型也可以是一个对象。不要使用data作为字段,因为data意义不明确。尽管现在业界普遍使用data,但是加上axios封装响应体也会加上data,结果会写成data.data这种取值,很容易脑子短路。

  4. 不要字段套字段,应尽量扁平。

  5. total是可选属性,表示数组资源总数。还可以加其他的字段传递别的数据。

  6. 在HTTP码不是2开头的情况下,除了msg,不要有其他属性。

然后说POST、PUT、DELETE的响应体

{
    msg: '修改成功'
}
  1. 如果200前提下,就返回msg就可以了,修改就是“修改成功”,删除就是“删除成功”,新增就是“新增成功”、“创建成功”等等的。

  2. 总会有失败的可能,比如删除失败,资源被别人先删了,你再删就是删除失败,这时候HTTP状态码不应是200(具体是多少看你们团队的规范),msg应当是删除失败:资源已被删除这类提示。
    其他的,比如“支付成功”和“支付失败”,一般来讲,成功,则页面路由会变化,进入下一个环节,失败,则原地弹出提示,可能要求用户换一种支付方式或者放弃支付,因此,失败的HTTP状态码不应是200(具体是多少也看你团队的规范),msg应当是支付失败:卡余额不足这类的话。

你可能感兴趣的:(HTTP码是200,响应体的code是500,什么鬼?)