登录功能中,使用Axios 的响应拦截器对于错误提示进行重构。
原代码:

//form实例统一校验
const formRef = ref(null);
const router = useRouter();
const doLogin = () => {
    formRef.value.validate(async (valid) => {
        // valid: 所有表单都通过校验  才为true
        //console.log(valid)
        if (valid) {
            //console.log(form.value)
            const { account, password } = form.value
            try {
                const res = await loginAPI({ account, password });
                console.log(res)
                ElMessage({ type: 'success', message: '登录成功' })
                router.replace({ path: '/' })
            } catch (e) {
                console.log(e)
                ElMessage({ type: 'error', message: e.response.data.message })
            }
        }
    })
}

将catch中捕获的错误信息放在Axios 的响应拦截器中处理,减少组件中的代码量:

// axios响应式拦截器
// 一般进行错误的统一提示,token失效的处理等
http.interceptors.response.use(res => res.data, e => {
    //统一错误提示
    ElMessage({
        type: 'error',
        message: e.response.data.message
    })
    return Promise.reject(e)
})

自此,可以删除组件中的try…catch中的catch部分:

const doLogin = () => {
    formRef.value.validate(async (valid) => {
        // valid: 所有表单都通过校验  才为true
        //console.log(valid)
        if (valid) {
            //console.log(form.value)
            const { account, password } = form.value
            const res = await loginAPI({ account, password });
            console.log(res)
            ElMessage({ type: 'success', message: '登录成功' })
            router.replace({ path: '/' })
        }
    })
}

关于http.interceptors.response.use()中的参数介绍

在 Axios 中,res 和 e 参数分别代表成功的响应对象和错误对象。这些参数是由 Axios 在请求完成时传递给响应拦截器函数的。让我们深入了解一下这些参数是从哪里来的,以及 Axios 如何处理它们。

res 和 e 参数的来源
成功的响应 (res)

当 Axios 发出一个 HTTP 请求并成功接收到服务器的响应时,它会将该响应对象传递给 onFulfilled 函数。这个响应对象包含了从服务器返回的所有数据和元信息。

http.interceptors.response.use(
  res => res.data,  // `res` 是成功的响应对象
  e => Promise.reject(e)  // `e` 是错误对象
);

这里的 res 是一个典型的 Axios 响应对象,它包含以下属性:

data: 服务器返回的数据。
status: HTTP 状态码(例如 200、404)。
statusText: HTTP 状态文本(例如 “OK”、“Not Found”)。
headers: 服务器响应头。
config: 用于生成请求的配置信息。
request: 生成这个响应的请求对象。
错误的响应 (e)

当 Axios 发出一个 HTTP 请求但未能成功接收到服务器的响应,或者接收到一个非 2xx 的状态码时,它会将该错误对象传递给 onRejected 函数。这个错误对象包含了错误的详细信息。

http.interceptors.response.use(
  res => res.data,  // `res` 是成功的响应对象
  e => Promise.reject(e)  // `e` 是错误对象
);

这里的 e 是一个包含错误信息的对象,可能包含以下属性:

message: 错误信息。
name: 错误名称。
stack: 错误的堆栈信息(用于调试)。
config: 用于生成请求的配置信息。
code: 错误代码(例如 ECONNABORTED 表示请求超时)。
request: 生成这个错误的请求对象。
response: 如果服务器有响应但状态码不在 2xx 范围内,则包含响应对象。

Axios 内部处理流程

让我们看看 Axios 内部是如何处理响应和错误的。

发送请求

Axios 使用 axios.request(config) 或类似方法发送 HTTP 请求。当请求发送出去后,Axios 会等待服务器的响应。

接收响应

当服务器响应时,Axios 会首先检查 HTTP 状态码。如果状态码在 2xx 范围内,Axios 会将响应对象视为成功,并传递给 onFulfilled 函数。如果状态码不在 2xx 范围内,或者请求过程中发生了错误,Axios 会将错误对象传递给 onRejected 函数。

拦截器处理

任何已注册的拦截器都会在请求发送和响应接收后执行。对于响应拦截器,成功的响应会被传递给第一个 onFulfilled 函数进行处理,如果所有 onFulfilled 函数都成功执行,最终返回处理后的响应数据。对于错误响应,错误对象会被传递给第一个 onRejected 函数,如果所有 onRejected 函数都执行成功,最终返回处理后的错误对象。

完整示例

以下是一个完整的示例,展示了 Axios 如何通过响应拦截器处理成功的响应和错误响应:

import axios from 'axios';

// 创建 Axios 实例
const http = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 1000,
  headers: { 'X-Custom-Header': 'foobar' }
});

// 添加响应拦截器
http.interceptors.response.use(
  res => {
    // 处理成功的响应
    console.log('响应成功:', res);
    return res.data;  // 返回响应数据
  },
  e => {
    // 处理错误的响应
    console.error('响应错误:', e);
    if (e.response) {
      console.error('响应错误数据:', e.response.data);
      console.error('响应错误状态码:', e.response.status);
      console.error('响应错误头:', e.response.headers);
    } else if (e.request) {
      console.error('请求错误:', e.request);
    } else {
      console.error('请求设置错误:', e.message);
    }
    return Promise.reject(e);  // 拒绝 Promise 并返回错误对象
  }
);

// 发送请求
http.get('/some-endpoint')
  .then(data => {
    console.log('请求数据:', data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

在这个示例中,响应拦截器 http.interceptors.response.use 接受两个参数:

一个处理成功响应的函数,它接收 res 参数并返回 res.data。
一个处理错误响应的函数,它接收 e 参数并记录错误信息,最后拒绝(reject)这个错误对象。
通过这种方式,Axios 可以统一处理所有 HTTP 请求的响应和错误,简化了代码逻辑并提高了代码的可维护性。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部