我有一个带有刷新 token 的 jwt 身份验证系统。 每 5 分钟客户端浏览器必须请求一个新的 accessToken,其中的刷新 token 保存在 localStorage 中。
为此,我在每个 AJAX 调用中都使用了发送前函数。
$.ajaxSetup({
beforeSend: addAuthHeader,
});
function addAuthHeader(xhr) {
if(Math.round(new Date() / 1000) >= sessionStorage.getItem('jwt_exp')) {
console.log('JWT expired. Refreshing now...');
$.ajax({
method: 'POST',
url: '/auth/token/refresh',
beforeSend: function (xhr) { },
data: { token: localStorage.getItem('refreshToken') },
// TODO: FIXME: Synchronous are deprected
async: false,
}).done(function (data) {
sessionStorage.setItem('jwt', data.accessToken);
sessionStorage.setItem('jwt_exp', data.exp);
xhr.setRequestHeader('Authorization', 'Bearer ' + data.accessToken);
console.log('Authorization', 'Bearer ' + data.accessToken);
});
} else {
xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
console.log('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
}
}
如您所见,我现在使用同步请求。 但这些已被弃用:
[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
有什么我可以异步做的事情吗?
运行第二个 ajax 调用不会更改 headers => beforeSend 不会等到一切完成
最佳答案
beforeSend
属性在发送请求之前触发,但请求不会等待其完成。这是设计使然。
为了创建您的功能,我会将您的请求包装在一个特殊的函数中,将您想要的请求放在最后的 addAuthHeader
请求的 .done 函数中。
大致如下:
function sendRequestWithAuth(requestFunction) {
if(Math.round(new Date() / 1000) >= sessionStorage.getItem('jwt_exp')) {
console.log('JWT expired. Refreshing now...');
$.ajax({
method: 'POST',
url: '/auth/token/refresh',
beforeSend: function (xhr) { },
data: { token: localStorage.getItem('refreshToken') },
// TODO: FIXME: Synchronous are deprected
async: false,
}).done(function (data) {
sessionStorage.setItem('jwt', data.accessToken);
sessionStorage.setItem('jwt_exp', data.exp);
xhr.setRequestHeader('Authorization', 'Bearer ' + data.accessToken);
console.log('Authorization', 'Bearer ' + data.accessToken);
requestFunction();
});
} else {
xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
console.log('Authorization', 'Bearer ' + sessionStorage.getItem('jwt'));
requestFunction();
}
}
这将确保在执行插入 requestFunction()
回调中的任何函数之前发送和接收刷新请求。
要传递 xhr.setRequestHeader,您可以将 is 作为参数传递给 requestFunction,如下所示:requestFunction(data.accessToken);
或 requestFunction(sessionStorage.getItem('jwt) '));
然后将值插入到函数内的请求中。
关于javascript - $.ajax beforeSend 不等待其他ajax请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51378264/