Axios 请求拦截器等待 ajax 调用完成
Axios Request Interceptor wait until ajax call finishes
我有一个用于 axios 调用的请求拦截器。它会检查我的 jwt 令牌并在必要时调用刷新。
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;
});
此代码正确调用刷新并保存新令牌,但原始调用在拦截器请求完成之前不会保持,因此使用过期令牌。
所以,我想我需要从拦截器进行同步调用。
避免同步调用 HTTP 请求,因为它们只会让您的应用程序挂起。
您在这里需要做的是使调用代码异步 - 与任何回调、承诺或异步相关的一般规则是,一旦您异步,所有内容都需要异步。
此处,axios.get
return是一个 Promise
- 一个跟踪异步 HTTP 请求并在其完成后解析的对象。你需要return那个,而不是config
。
我们通过 return 创建一个新的 Promise
- 如果需要新令牌的 HTTP 请求,它会等待它,如果不需要,它可以立即 resolve
。
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
,一旦你 一切 需要 return 一个 Promise
.
如果您可以使用 async
/await
,这会 多 容易 - 现代浏览器支持的新关键字,如果您需要支持旧用户,则可以转换.有了这些,您只需将 Promise
调用与 await
关键字内联。
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 调用的请求拦截器。它会检查我的 jwt 令牌并在必要时调用刷新。
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;
});
此代码正确调用刷新并保存新令牌,但原始调用在拦截器请求完成之前不会保持,因此使用过期令牌。
所以,我想我需要从拦截器进行同步调用。
避免同步调用 HTTP 请求,因为它们只会让您的应用程序挂起。
您在这里需要做的是使调用代码异步 - 与任何回调、承诺或异步相关的一般规则是,一旦您异步,所有内容都需要异步。
此处,axios.get
return是一个 Promise
- 一个跟踪异步 HTTP 请求并在其完成后解析的对象。你需要return那个,而不是config
。
我们通过 return 创建一个新的 Promise
- 如果需要新令牌的 HTTP 请求,它会等待它,如果不需要,它可以立即 resolve
。
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
,一旦你 一切 需要 return 一个 Promise
.
如果您可以使用 async
/await
,这会 多 容易 - 现代浏览器支持的新关键字,如果您需要支持旧用户,则可以转换.有了这些,您只需将 Promise
调用与 await
关键字内联。
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;
});