javascript - $.ajax beforeSend 不等待其他ajax请求

标签 javascript jquery ajax asynchronous xmlhttprequest

我有一个带有刷新 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/

相关文章:

c# - 是什么导致我的 ASP.NET MVC/AJAX 网站上出现这些 SQL 转换错误? [视频显示问题]

javascript - 需要澄清使用 0 和三元运算符

javascript - jQuery 和 AJAX 调用的最佳实践

JavaScript 无法处理更多加载的内容

javascript - jQuery 现在显示短语变量值

javascript - 在 css 文件 href Javascript 中更改 css 类背景

javascript - 如何在单击按钮时获取多个复选框值?

javascript - API数据提取

javascript - D3.js(威尔金森型)点图示例

jquery - 这个 jquery 有问题