vue3笔记(16)axios定制化

后端使用GO的JNS框架,关于请求参数的错误码code归结到400,在code同一层级使用reason标注错误原因。前端框架中使用了axios库,联调中发现后端定义的400错误reason前端捕捉不到。
这篇记录前后端交互出现的问题。

问题来源

请求成功返回200,如下格式都没有异议。

1
2
3
4
5
6
7
8
{ 
code: 200,
data: {
data: {data: Array(7), page: 1, total: 7}
msg: "success"
status: 200
}
}

问题在于请求失败,失败的原因在于何处,是否涉及到业务错误?

状态码定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
502 网关错误
503 Service Unavailable
504 网关超时

规范确定

涉及到业务错误,后端返回状态码任然为200,需要后端将具体的业务错误返回给前端,返回数据结构如下:

1
2
3
4
5
6
7
8
{
code: 200,
data: {
result: "fail",
errorcode: 10001, # 业务相关的错误编码
message: “计算资源不可用” # 业务相关的错误描述
}
}

涉及到40x之类的错误,后端返回状态码为40x,同时需要在返回数据结构中注明具体错误。

1
2
3
4
5
6
7
{
code: 40x,
data: {
result: "fail",
message: “计算资源不可用” # 业务相关的错误描述
}
}

axios拦截器捕捉

可以在request.ts中通过axios拦截器获取捕捉的error,通过error描述对比直接进行处理,适用于code专一性表示错误的项目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 请求拦截器
axios.interceptors.request.use(
(config: AxiosRequestConfig) => {
if (UserModule.token) {
config.headers["Authorization"] = "JWT " + UserModule.token;
}
return config;
},
(error) => {
Promise.reject(error);
}
);

axios.interceptors.response.use(
(res: AxiosResponse) => {
return res;
},
(error) => {
console.log("error=", error);
if (error == "Error: Request failed with status code 403") {
ElMessage.error("当前没有查看权限,请联系管理员。");
} else {
return Promise.reject(error);
}
}
);

validateStatus配置

通过在request.ts中增加validateStatus配置,获取错误code,可以直接返回到调用接口的位置。

1
2
3
4
5
6
7
8
9
10
11
12
export function deleteDataBatch(url: string, json: object) {
return axios({
url: url,
method: "delete",
data: json,
validateStatus: function (status) {
console.log('status=', status) // 403
return status < 500;
}
})
.then((res) => res)
.catch((error) => error);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
deleteBatchStandard({ ids })
.then((res) => {
if(!res) {
ElMessage.error("这里需要前端处理错误信息展示");
}else {
const { status, data, msg } = res.data;
if (status == 200) {
//success
} else {
ElMessage.error(msg); //业务信息错误
}
}

})
.catch((error) => {
ElMessage.error("服务器修复中,请稍后重试!");
});
})
.catch((error) => {
console.log('error=',error) //
});

附录
axios API
axios 详细配置