Axios 请求拦截器等待 ajax 调用完成 [英] Axios Request Interceptor wait until ajax call finishes

查看:46
本文介绍了Axios 请求拦截器等待 ajax 调用完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于 axios 调用的请求拦截器.它会检查我的 jwt 令牌并在必要时调用刷新.

I have an request interceptor for axios calls. It checks my jwt token and call for refresh if necessary.

axios.interceptors.request.use((config) =>{

    const state = store.getState(); // get renewed state
    const time = Math.floor( new Date().getTime() / 1000 );

    if( 
        ! state.app.jwtRefreshOnRequest 
        && time >= state.jwt.expires - 120
        && state.jwt.refresh_before > time
    ){ // expiring in 2 min. refresh    

        //dispatch({type: 'JWT_REFRESH_REQUEST'});
        axios.get( API_BASE_URL + '/auth/refresh')
            .then(function(response){
                // dispatch({type: 'JWT_REFRESH_SUCCESS', payload: response.data});
                axios(config).then(resolve, reject);
            })
            .catch(function(err){               
                reject(err);
        });

    }       

    return config;
}); 

此代码正确调用刷新并保存新令牌,但原始调用在拦截器请求完成之前不会保持,因此使用过期令牌.

This code calls the refresh correctly and saves the new token but the original call doesn't holds until the interceptor request is done, so the expired token is used.

所以,我想我需要从拦截器进行同步调用.

So, I guess I need to make synchronous call from interceptor.

推荐答案

避免同步调用 HTTP 请求,因为它们只会使您的应用程序挂起.

Avoid synchronous calls for HTTP requests, as they just make your application hang.

此处您需要做的是使调用代码异步 - 与回调、promise 或异步相关的任何内容的一般规则是,一旦您是异步的,一切都必须是异步的.

What you need to do here is make the calling code asynchronous - the general rule with anything callback, promise or async related is that once you are async everything needs to be async.

这里,axios.get 返回一个 Promise - 一个跟踪异步 HTTP 请求并在它完成后解析的对象.您需要返回那个,而不是 config.

Here, axios.get returns a Promise - an object that keeps track of the asynchronous HTTP request and resolves once it has finished. You need to return that, rather than the config.

我们通过返回一个新的Promise来做到这一点——如果需要一个新令牌的HTTP请求,它会等待它,如果没有,它可以立即resolve.>

We do that by returning a new Promise - if an HTTP request for a new token is required it waits for it, if no it can resolve immediately.

axios.interceptors.request.use(config =>
    new Promise((resolve, reject) => {
        // ... your code ...

        axios.get( API_BASE_URL + '/auth/refresh')
            .then(response => {
                // Get your config from the response
                const newConfig = getConfigFromResponse(response);

                // Resolve the promise
                resolve(newConfig);
            }, reject);

        // Or when you don't need an HTTP request just resolve
        resolve(config);
    })
}); 

每当您看到 then 时,您都在处理 Promise,一旦您成为 一切 都需要返回一个 Promise.

Whenever you see that then you're dealing with Promise, and once you are everything needs to return a Promise.

如果您可以使用 async/await,这会容易得多 - 现代浏览器支持的新关键字,如果您需要支持旧版,则可以转译用户.使用这些,您可以将 Promise 调用与 await 关键字内联.

This is much easier if you can use async/await - new keywords supported by modern browsers and transpilable if you need to support legacy users. With these you can just put the Promise call inline with the await keyword.

axios.interceptors.request.use(async config =>

    // ... your code ...

    if(/* We need to get the async token */) {
        const response = await axios.get( API_BASE_URL + '/auth/refresh');
        config = getConfigFromResponse(response);
    }

    return config;
}); 

这篇关于Axios 请求拦截器等待 ajax 调用完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆