使用 Axios 对 React 发送的请求 (request) 和响应的数据 (response) 进行处理

时之世 发布于 2024-09-30 444 次阅读 预计阅读时间: 3 分钟 最后更新于 2024-09-30 683 字 无~


AI 摘要

在进行一些请求时,我们常常需要加入自定义请求头,比如`Authorization: `Bearer ${token}``, 但是如果直接在请求时加入 header 属性,无论是浏览器还是后端都接收不到任何你定义的请求头。 这时我们可以使用拦截器做处理,拦截器有 request 和 response 两种拦截;设定自定义请求头也有两种方法。当设置请求和响应拦截器时,我们可以对数据进行预处理。例如,创建 Axios 实例,并使用拦截器对请求和响应数据进行处理。

为请求 (Request) 增加自定义请求头 (content-type)

在进行一些请求时,我们常常需要加入自定义请求头,比如`Authorization: `Bearer ${token}``, 但是如果直接在请求时加入 header 属性,无论是浏览器还是后端都接收不到任何你定义的请求头

比如这里的后端过滤器需要接收自定义的 authorizationlinkid, 但是由于无法接收,就会出现各种问题。

这时我们需要了解为什么会出现这样的问题,网上大多是这两种:

  • axios 请求封装直接设置 headers 为一个新对象,这种不管接口请求中设置任何 header 都会被覆盖
  • 浏览器出于安全考虑,不支持自定义请求头 (个人更倾向于这种,因为使用 ajax 也会出现无法自定义请求头的情况)

用拦截器做处理

我们可以使用拦截器做处理,拦截器有 requestresponse 两种拦截;设定自定义请求头也有两种方法。

创建 Axios 实例

/**
 * 创建 Axios 实例
 */
const apiClient = axios.create({
    timeout: 15000,  // 设置超时时间
    headers: {
        //设置为键值对
        'Content-Type': 'application/x-www-form-urlencoded',
    },
});

设置 request 请求拦截器

  • 方法一
// 添加请求拦截器
apiClient.interceptors.request.use(
    async (request) => {
        try {

            if (typeof window !== 'undefined' && window.localStorage) {
                const token = getToken();
                const linkId = getLinkId();
                console.log("token: " + token);
                Object.entries({
                    Authorization: `Bearer ${token}`,
                    LinkId: `${linkId}`
                }).forEach(([key, value]) => (request.headers[key] = value));
                // 对请求数据进行加密
                // let linkKey= JSON.parse(window.localStorage.getItem('link')).linkKey || null;
                // request.data = AESEncrypt(request.data, linkKey);
            }
            return request;
        } catch (err) {
            console.log(`科室隔离配置查询失败:${err}`);
        }
        return request;
    },
    error => {
        
        return Promise.reject(error);
    }
);
// 请求拦截器
  /****** request拦截器==>对请求参数做处理 ******/
service.interceptors.request.use(config => {
  app.$vux.loading.show({
    text: '数据加载中……'
  });
 
  let headers = {
        "Accept-Language":"en-CN;q=1.0",
        "source_type":"apple-appstore",
        "version_code":"5.4.8",
        "Content-Type":"application/json",
        "push_device_type":"4",
        "Accept": "*/*"
      }
  config.headers = {...headers,...config.headers}//如果不这样写, 那么在接口中设置的header都会被覆盖
  return config;
}, error => { //请求错误处理
  app.$vux.toast.show({
    type: 'warn',
    text: error
  });
  Promise.reject(error)
})

添加 response 响应拦截器


// 添加响应拦截器
apiClient.interceptors.response.use(
    response => {
        // 对响应数据进行解密
        if (typeof window !== 'undefined' && window.localStorage) {
            // 浏览器环境
            console.log("response: "+JSON.stringify(response));
            let linkKey= JSON.parse(window.localStorage.getItem('link')).linkKey || null;
            return AESDecrypt(response.data, linkKey);
        }
        if (typeof window !== 'undefined' && window.localStorage) 
            console.log("response2: "+JSON.stringify(response));
        return response.data;
    },
    error => {
        // 处理错误响应
        return error.response.data;
        // return Promise.reject(error);
    }
);

当设置请求和响应拦截器时,我们可以对数据进行处理,而设置自定义请求头就包含在里面