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 或异步相关的任何内容的一般规则是,一旦您是异步的,一切都必须是异步的.
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屋!