Выполнение функции .done () для Ajax-запроса повторно в .ajaxError () - PullRequest
2 голосов
/ 08 октября 2019

У меня есть глобальная ajaxError() функция для веб-приложения. Веб-приложение использует проверку подлинности Cookie с помощью Azure AD OpenIdConnect. Я пытаюсь обработать случай, когда срок действия файла cookie истекает до того, как будет сделан ajax-запрос к моему API. Если срок действия файла cookie истек, API вернет ответ 302 при входе в систему Microsoft, который затем попытается повторно авторизовать пользователя, но не удастся из-за CORS. Когда это происходит, я добавляю iframe на страницу с src, настроенным на URL в моем приложении, который будет повторно запрашивать пользователя и возвращать обновленные файлы cookie.

Я повторно отправляю запрос ajax следующим образом:

$(document).ajaxError(function (event, request, settings, thrownError) {
        if (/* CORS error */) {
            var iframe = document.createElement("iframe");
            iframe.style.display = "none";
            iframe.src = reAuthUri;
            document.body.appendChild(iframe);

            // Re-send request.
            $.ajax(settings);
        }
    });

Это работает, повторно отправляет запрос с обновленными файлами cookie и успешно, но мой .done() обратный вызов никогда не срабатывает. Пример:

$.ajax({
  type: "GET",
  url: "/api/things/"
}).done(result => doSomething());

doSomething() не вызывается. Если я изменю ajax-запрос на использование success вместо done(), то он будет работать:

$.ajax({
  type: "GET",
  url: "/api/things/",
  success: result => doSomething()
});

Однако, поскольку .done() является предпочтительным способом обработки обратных вызовов ajax сейчас, каждый запрос ajax вприложение написано с использованием его вместо старого свойства success. Итак, есть ли способ получить действие .done() для запроса, вызываемого при повторной отправке запроса в .ajaxError()?

1 Ответ

3 голосов
/ 08 октября 2019

На самом деле вы никогда не отправляете повторно свой запрос ajax, вы отправляете новый запрос с точно такой же настройкой, что и первый. Однако, поскольку функция $.ajax возвращает объект Deferred, который в этом состоянии отклоняется, получить обратный вызов done невозможно.

Вам необходимо создать новый обратный вызов done для повторной отправки вашего «нового» ajax-запроса или использовать атрибут success в настройке, поскольку он передается в функцию ajaxError.

Вы также можете отправить свой обратный вызов done со своими настройками и получить его с помощью функции ajaxError. Обратите внимание, что doneFunction не является стандартным параметром jQuery ajax - я его добавил.

// THE GLOBAL CODE 
$(document).ajaxError(function (event, request, settings, thrownError) {
  let originalDoneCallback = settings.doneFunction;
  // here we are calling directly the done attribute to prove it is the same as before.
  originalDoneCallback()
  // Since it's a function, you could use it as so. 
  //$.ajax(settings).done(originalDoneCallback);
});



// THE LOCAL CODE 
// we are using this object to prevent having to code our done function twice.
let ajaxSettings =  {
  doneFunction: function() {
    console.log('new done!')
  }
};


$.ajax('https://test.test',ajaxSettings).done(ajaxSettings.doneFunction);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...