运行 多次 API 调用时仅响应拦截器一次
run response interceptor only once when multiple API calls
我有一个这样的拦截器
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
})
}
})
一切正常,但如果我在我的例子中有 4 API 调用一个 React 组件,并且发生此错误,相同的代码将 运行 4 次,意思是 4 次我将发送我的刷新令牌并获取身份验证令牌,显然我只想 运行 一次
您是否考虑过对请求进行 throttle/debounce 包装? lodash 都内置了。
这是两者的一个很好的例子。虽然是下划线但是一样的区别。
http://jsfiddle.net/missinglink/19e2r2we/
...也许您的情况是这样的?
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return _.debounce(axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
}), 1000)
}
})
不过这样可能更好?
axios.interceptors.response.use(undefined, _.debounce(
我认为您可以使用类似的方式对身份验证请求进行排队:
let authTokenRequest;
// This function makes a call to get the auth token
// or it returns the same promise as an in-progress call to get the auth token
function getAuthToken() {
if (!authTokenRequest) {
authTokenRequest = makeActualAuthenticationRequest();
authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);
}
return authTokenRequest;
}
function resetAuthTokenRequest() {
authTokenRequest = null;
}
然后在你的拦截器中...
axios.interceptors.response.use(undefined, err => {
const error = err.response;
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return getAuthToken().then(response => {
saveTokens(response.data);
error.config.__isRetryRequest = true;
return axios(error.config);
});
}
});
希望对您有所帮助 ;)
我有一个这样的拦截器
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
})
}
})
一切正常,但如果我在我的例子中有 4 API 调用一个 React 组件,并且发生此错误,相同的代码将 运行 4 次,意思是 4 次我将发送我的刷新令牌并获取身份验证令牌,显然我只想 运行 一次
您是否考虑过对请求进行 throttle/debounce 包装? lodash 都内置了。 这是两者的一个很好的例子。虽然是下划线但是一样的区别。
http://jsfiddle.net/missinglink/19e2r2we/
...也许您的情况是这样的?
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return _.debounce(axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
}), 1000)
}
})
不过这样可能更好?
axios.interceptors.response.use(undefined, _.debounce(
我认为您可以使用类似的方式对身份验证请求进行排队:
let authTokenRequest;
// This function makes a call to get the auth token
// or it returns the same promise as an in-progress call to get the auth token
function getAuthToken() {
if (!authTokenRequest) {
authTokenRequest = makeActualAuthenticationRequest();
authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);
}
return authTokenRequest;
}
function resetAuthTokenRequest() {
authTokenRequest = null;
}
然后在你的拦截器中...
axios.interceptors.response.use(undefined, err => {
const error = err.response;
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return getAuthToken().then(response => {
saveTokens(response.data);
error.config.__isRetryRequest = true;
return axios(error.config);
});
}
});
希望对您有所帮助 ;)