ant design pro 踩坑和填坑 —— request.js
问题:异常统一处理
描述:
在大部分情况下,后台请求异常时,都会返回对应的状态码,400,404,500等等,但是,现在一些后端设计返回response.status都为200,通过code或者status来判断请求是否正确,从而开始了这个坑的攻克。
问题处理:(此处用登录状态失效为例,status为3时登录失效)
首先是发现了response.json()是一个promise,所以在处理的时候肯定是使用promise的方式来处理:
const res = response.json();
res.then(data => {
if (data.status === 3) {
const errortext = codeMessage[401];
const error = new Error(errortext);
error.name = response.status;
error.response = response;
throw error;
}
return data;
});
刚开始以为这样处理就可以了,没有return
这个promise
,所以在models里call了一个undefined,相当郁闷,所以开始走了一些歧路:
一直想着返回值是个Promise,所以就想着自己造一个
const res = response.json();
const promiseRes = res.then(data => {
const promise = new Promise((resolve) => {
if (data.status === 3 {
message.error('登录状态失效,请重新登录', 3, () => {
window.g_app._store.dispatch({
type: 'login/logout',
});
});
}
resolve(data);
})
return promise;
})
return promiseRes;
虽然好像是解决了问题,但是又是resolve又是好几层的return,怎么看都觉得别扭,但是由于项目忙就将就用了一段时间。
后来意识到了res本身就是一个promis,所以直接去掉了那一层别扭的promis(PS: 心里感觉各种舒畅)
const res = response.json();
return res.then(data => {
if (data.status === 3) {
const errortext = codeMessage[401];
const error = new Error(errortext);
error.name = response.status;
error.response = response;
throw error;
}
return data;
});
问题:fetch若进入catch会导致代码出错
描述:
这个问题产生于后台请求报常规错误时产生的,当后台返回状态码为500或者401后,进入catch,会发现antd pro 返回个啥,return;
???啥,这不就是返回了一个undefined么,然后导致了代码报undefined的错误,更离谱的是,是401的时候,跳转登录,重新登录后,出错的列表页,列表还是为空,甚至没有重新请求接口。
问题解决:
解决办法一: 使用神奇的 ...
put({
type: '',
payload: {
...response
}
});
// 同样的在reduce里面也需要做相应的处理
return {
...state,
some: { ...payload }
}
解决办法二:暴力解决,可能是一个不是办法的办法,但是好像有点卵用
return;
改成return e;
所以求一个更好的解决办法,拜谢!!!
一些小问题:
1.当body的值是一个字符串时:
newOptions.body = JSON.stringify(newOptions.body); // 当为字符串的时候会有两对引号
newOptions.body = typeof newOptions.body !== 'string' ? JSON.stringify(newOptions.body) : newOptions.body; // 所以加一个判断
2.修改整体请求头'Content-Type': 'application/x-www-form-urlencoded'
仅仅需要改成qs的stringify: s=1&a=2
import { stringify } from 'qs';
/*
* 此处省略
*/
newOptions.body = typeof newOptions.body !== 'string' ? stringify(newOptions.body) : newOptions.body;