后端使用GO的JNS框架,关于请求参数的错误码code归结到400,在code同一层级使用reason标注错误原因。前端框架中使用了axios库,联调中发现后端定义的400错误reason前端捕捉不到。
这篇记录前后端交互出现的问题。
问题来源
请求成功返回200,如下格式都没有异议。
| { code: 200, data: { data: {data: Array(7), page: 1, total: 7} msg: "success" status: 200 } }
|
问题在于请求失败,失败的原因在于何处,是否涉及到业务错误?
状态码定义
| 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,需要后端将具体的业务错误返回给前端,返回数据结构如下:
| { code: 200, data: { result: "fail", errorcode: 10001, # 业务相关的错误编码 message: “计算资源不可用” # 业务相关的错误描述 } }
|
涉及到40x之类的错误,后端返回状态码为40x,同时需要在返回数据结构中注明具体错误。
| { 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,可以直接返回到调用接口的位置。
| export function deleteDataBatch(url: string, json: object) { return axios({ url: url, method: "delete", data: json, validateStatus: function (status) { console.log('status=', status) 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) { } else { ElMessage.error(msg); } } }) .catch((error) => { ElMessage.error("服务器修复中,请稍后重试!"); }); }) .catch((error) => { console.log('error=',error) });
|
附录
axios API
axios 详细配置