最初,我在kendo UI数据源的beforeSend事件中使用setRequestHeader()来在http标头中设置Bear令牌,并且效果很好。
现在,为了处理令牌超时问题,我想在beforeSend事件中刷新令牌。但是因为Fetch是一个异步函数,所以beforeSend事件将立即返回,因此kendo数据源使用了旧令牌,最后得到401。
我检查过beforeSend不支持异步,所以有什么主意可以达到这个目的吗?
更新
根据建议,我使用了ajaxSend()
,每次调用ajax调用时都会调用它。在ajaxSend()内部,我使用fetch(跨域)刷新令牌,以便下一个ajax调用将在请求标头中使用新令牌:
$(document).ajaxSend(function (e, xhr, options) {
console.log('Event: ', e);
console.log('xhr: ', xhr);
console.log('Options: ', options);
console.log('Old access_token: ', my_user.access_token);
let formData = 'grant_type=refresh_token&refresh_token=' + my_user.refresh_token;
fetch('url/Token', { //---cross domain server
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded'},
body: formData })
.then(data => data.json())
.then(user => {
if (user.access_token) {
xhr.setRequestHeader('Authorization', 'Bearer ' + user.access_token);
console.log('New access_token: ', user.access_token);
}
else {
console.error('error');
}
}).catch(error => {
console.error(error.message);
})
});
但是奇怪的是,不知道为什么接下来的ajax调用仍然使用'Old access_token'而不是''new access_token'。
第二次更新
我发现ajaxSend
也不支持异步。
[还有一个帖子与我的问题相同。 jQuery: how to make ajaxSend wait for another Ajax response before proceeding?
该帖子中的答案表明,除了使原始的ajax请求等待之外,另一种方法是中止原始请求,并在异步调用(我的请求被获取)完成后重试该请求。我以前有这样的想法,但是它不适合我的情况,因为我使用Kendo UI网格来等待响应,然后网格将自动更新。如果我中止原始请求并重试,则Kendo UI网格将不会自动更新,因为该请求已中止。除非我通过代码手动更新Kendo网格,但这不是我的意图。
您可以尝试使用ajaxSend
拦截请求。
$(document).ajaxSend(function (e, xhr, options) {
console.log('Event: ', e);
console.log('xhr: ', xhr);
console.log('Options: ', options);
xhr.setRequestHeader('Authorization', 'Bearer ' + 'jwt');
});
这将拦截每个请求。我使用read
和fetch
dataSource方法对其进行了测试。
Note:从jQuery 1.8开始,此方法应仅附加到文档。