【问题标题】:$.ajax beforeSend not waiting for other ajax request$.ajax beforeSend 不等待其他 ajax 请求
【发布时间】:2020-05-26 17:00:00
【问题描述】:

我有一个带有 refreshToken 的 jwt 身份验证系统。 每 5 分钟,客户端浏览器必须使用保存在 localStorage 中的 refreshToken 请求一个新的 accessToken。

为此,我在每次 AJAX 调用中都使用了 before send 函数。

$.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 不会等到一切都完成

【问题讨论】:

    标签: javascript jquery ajax asynchronous xmlhttprequest


    【解决方案1】:

    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')); 然后将值插入函数内的请求。

    【讨论】:

      【解决方案2】:

      您在代码中使用的 JQuery [async: false] 属性已弃用。

      尝试使用 async/await 函数并像这样调用 ajax:

      async function fun() {
          ...
          await $.ajax({
              ...
      

      它对我有用。

      【讨论】:

        【解决方案3】:

        另一种选择是取消您在beforeSend 中的请求(通过返回false)并使用您的新标头创建一个新请求。例如,这对我有用,并且会自动应用于我的所有请求,而无需调用任何包装器:

        $.ajaxSetup({
            beforeSend: function (xhr, settings)
            {
                firebase.auth().currentUser.getIdToken()
                    .then(function(result) {
                        $.ajax($.extend(settings, {
                            headers: {"X-Authorization-Firebase": result},
                            beforeSend: $.noop
                        }));
                    });
                return false;
            }
        });
        

        【讨论】:

        • 我正在尝试做类似的事情,但我似乎无法触发来自原始 ajax 调用的 thencatchalways 回调。
        猜你喜欢
        • 2015-07-19
        • 2018-08-05
        • 1970-01-01
        • 2014-02-19
        • 2015-02-21
        • 2014-04-24
        • 2017-06-12
        • 1970-01-01
        • 2020-08-17
        相关资源
        最近更新 更多