简体   繁体   English

拦截器上的axios多请求

[英]Axios multiple request on interceptor

I'm using the library axios in my react app.我在我的反应应用程序中使用库axios
I'm having a problem with the interceptor.我的拦截器有问题。

My question is let say I have three requests happening concurrently and I don't have the token, the interceptor calling the getUserRandomToken three time, I want the interceptor will wait until I'm getting the token from the first request and then continue to the others.我的问题是说我有三个请求同时发生并且我没有令牌,拦截器调用getUserRandomToken三次,我希望拦截器会等到我从第一个请求中获取令牌,然后继续其他。

PS the token he is with an expiration date so I also checking for it and if the expiration date is not valid I need to create a new token. PS 他的令牌有到期日期,所以我也检查它,如果到期日期无效,我需要创建一个新令牌。

This is the interceptor:这是拦截器:

 axios.interceptors.request.use( config => { /*I'm getting the token from the local storage If there is any add it to the header for each request*/ if (tokenExist()) { config.headers.common["token"] = "..."; return config; } /*If there is no token i need to generate it every time create a random token, this is a axios get request*/ getUserRandomToken() .then(res => { /*add the token to the header*/ config.headers.common["token"] = res; return config; }) .catch(err => { console.log(err); }); }, function(error) { // Do something with request error return Promise.reject(error); } );

How about singleton object that will handle the token generations?将处理令牌生成的单例对象怎么样? something similar to this:类似的东西:

const tokenGenerator ={
  getTokenPromise: null,
  token: null,
  getToken(){
    if (!this.getTokenPromise){
      this.getTokenPromise = new Promise(resolve=>{
        /*supposed to be a http request*/
        if (!this.token){
          setTimeout(()=>{
            this.token = 'generated';
            resolve(this.token);
          },0)
        }else{
          resolve(this.token);
        }
      })
    }
    return this.getTokenPromise;
  }

you can reference this same object from the interceptors.您可以从拦截器中引用相同的对象。

see example: JS FIddle reference: reference参见示例: JS Fiddle参考: 参考

You can return a Promise from interceptor callback to "wait" until promise fullfiles (this will fit your case).您可以从拦截器回调中返回一个 Promise 以“等待”直到承诺完整文件(这将适合您的情况)。 Check out this example:看看这个例子:

function axiosCall () {
  return new Promise((resolve, reject) => {
    Axios.post(URL, {apiKey}).then((response) => {
      resolve(response.data.message);
    }).catch((error) => {
      reject(error);
    });
  });
}

instance.interceptors.request.use((config) => {
  return axiosCall().then((tokenResponse) => {
    setWebCreds(tokenResponse);
    config.headers.Authorization = `Bearer ${tokenResponse}`;
    return Promise.resolve(config)
  }).catch(error => {
    // decide what to do if you can't get your token
  })
}, (error) => {
  return Promise.reject(error);
});

More details here: https://github.com/axios/axios/issues/754更多细节在这里: https : //github.com/axios/axios/issues/754

Following code doing certain tasks:以下代码执行某些任务:

  1. Update Token on 401在 401 上更新令牌
  2. Make a queue of failed requests while the token is refreshing.在令牌刷新时创建一个失败请求队列。
  3. Restore the original request after token refreshing.令牌刷新后恢复原始请求。
  4. Once the peculiar request is given 200, remove it from the queue.一旦特殊请求被赋予 200,就将其从队列中删除。

Config.js配置文件

import axios from 'axios'; import { AsyncStorage } from 'react-native'; import { stateFunctions } from '../../src/sharedcomponent/static'; const APIKit = axios.create({ baseURL: '', timeout: 10000, withCredentials: true, }); const requestArray = []; // Interceptor for Request export const setClientToken = token => { APIKit.interceptors.request.use( async config => { console.log('Interceptor calling'); let userToken = await AsyncStorage.getItem('userToken'); userToken = JSON.parse(userToken); config.headers = { 'Authorization': `Bearer ${userToken}`, 'Accept': 'application/json', "Content-Type": "application/json", "Cache-Control": "no-cache", } // console.log('caling ' , config) return config; }, error => { Promise.reject(error) }); }; // Interceptor for Response APIKit.interceptors.response.use( function (response) { if (requestArray.length != 0) { requestArray.forEach(function (x, i) { if (response.config.url == x.url) { requestArray.splice(i, 1); } }); } return response; }, function (error) { const originalRequest = error.config; requestArray.push(originalRequest); let reqData = "username=" + number + "&password=" + pin + "&grant_type=password" + "&AppType=2" + "&FcmToken=null"; // console.log('error ' , error); if (error.message === "Request failed with status code 401" || error.statuscode === 401) { if (!originalRequest._retry) { originalRequest._retry = true; return axios({ method: 'post', url: '/api/login', data: reqData, headers: { "Content-Type": "application/x-www-form-urlencoded", "Cache-Control": "no-cache", } }) .then(res => { let response = res.data; console.log('successfull Login', response) if (res.data.StatusCode == 200) { AsyncStorage.setItem('userToken', JSON.stringify(response.access_token)); stateFunctions.UserId = response.UserId; stateFunctions.CustomerContactID = response.CustomerContactID; let obj = { access_token: response.access_token, token_type: response.token_type, expires_in: response.expires_in, UserId: response.UserId, CustomerContactID: response.CustomerContactID, Mobile: response.Mobile, StatusCode: response.StatusCode } AsyncStorage.setItem('logindetail', JSON.stringify(obj)); if (requestArray.length != 0) { requestArray.forEach(x => { try { console.log(x, "request Url"); x.headers.Authorization = `Bearer ${response.access_token}`; x.headers["Content-Type"] = "application/x-www-form-urlencoded"; APIKit.defaults.headers.common["Authorization"] = `Bearer${response.access_token}`; APIKit(x) } catch (e) { console.log(e) } }); } return APIKit(originalRequest); } }) .catch(err => { console.log(err); }); } } return Promise.reject(error); } ); export default APIKit;

Home.js主页.js

 gettingToken = async () => { let userToken = await AsyncStorage.getItem('userToken'); userToken = JSON.parse(userToken); await setClientToken(userToken); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM