Axios请求拦截器等待直到ajax调用完成 [英] Axios Request Interceptor wait until ajax call finishes
问题描述
我有一个用于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或async相关的一般规则是,一旦异步,一切都必须是异步的.
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屋!