【问题标题】:Axios: combining data request from interceptors and from component before POSTAxios:在POST之前结合来自拦截器和组件的数据请求
【发布时间】:2020-01-17 03:04:50
【问题描述】:

我有这个函数动作

export function unlinkAccount(id) {
  return function(dispatch) {
    const data = {
      id: id
    };
    return userApi
      .post('/user/account/unlink', data)
      .then(res => console.log('SUCCESS: unlinkAccount -> ', res))
      .catch(err => console.log('ERROR: unlinkAccount -> ', err));
  };
}

但我也按照以下方式拦截请求

userApi.interceptors.request.use(
  async config => {
    const jwtToken = await refreshToken();
    if (jwtToken) {
      config.data = { accessToken: jwtToken };
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

这将使用来自拦截器的数据而不是unlinkAccount 函数对userApi 进行POST。有没有办法将这两种数据合并或作为“道具”传递给unlinkAccount 函数,因为我需要按照以下格式传递数据:

const data = {
   id: id,
   accessToken: jwtToken
}

谢谢。

【问题讨论】:

  • 拦截器中config.data的输出是什么?如果 config.data 是来自 unlinkAccount 函数的数据,您可以将其与拦截器数据合并,而不是重新分配给拦截器的数据(jwtToken)。
  • @WeiSengTan ya 你说得对,谢谢

标签: reactjs redux axios interceptor


【解决方案1】:

这是我过去所做的:

我认为,每次调用 api 时都传递 jwtToken 不是一个好方法。 如果你使用下面的,你只需要

const data = {
      id: id
    };
    return userApi
      .post('/user/account/unlink', data)

另外,你不需要每次都调用 refreshToken。

import axios from 'axios';

import { store } from '../index';
import { updateAuth } from '../redux/actions/auth';
import { apiURL } from '../config';

axios.defaults.baseURL = apiURL;

// Add a request interceptor
axios.interceptors.request.use(
  (config) => {
    const { tokenType, accessToken, loggedIn } = store.getState().auth;
    const token = `${tokenType} ${accessToken}`;
    if (loggedIn) {
      config.headers['Authorization'] = token;
    }
    config.headers['Content-Type'] = 'application/json';
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

//Add a response interceptor

axios.interceptors.response.use(
  (response) => {
    return response;
  },
  function(error) {
    const originalRequest = error.config;

    if (
      error.response.status === 401 &&
      (originalRequest.url === `${apiURL}auth/login` ||
        originalRequest.url === `${apiURL}auth/refresh-token`)
    ) {
      // router.history.push('/auth/login');
      return Promise.reject(error);
    }

    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      const { refreshToken } = store.getState().auth;
      const { email } = store.getState().user;

      return axios
        .post('/auth/refresh-token', {
          email,
          refreshToken
        })
        .then((response) => {
          const { data: res } = response;
          if (res.code === 200) {
            store.dispatch(updateAuth({ ...res.token }));
            const { tokenType, accessToken } = res.token;
            axios.defaults.headers.common[
              'Authorization'
            ] = `${tokenType} ${accessToken}`;
            return axios(originalRequest);
          }
        });
    }
    return Promise.reject(error);
  }
);

export default axios;

【讨论】:

  • 谢谢,会实现的。但就我而言,我仍然需要拦截器中的数据是动态的
【解决方案2】:

是的,只是想出解决方案,我只是将拦截器请求中的 config.data 更改为

if (jwtToken) {
      config.data = { accessToken: jwtToken, ...config.data };
    }

所以它会从组件中获取数据并在进行 POST 之前合并拦截数据。

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    相关资源
    最近更新 更多