15

Как управлять перенаправлением после вызова jQuery Ajax

16

Я использую метод <code>$.post()</code> для вызова сервлета с помощью Ajax и затем использую полученный HTML-фрагмент, чтобы заменить элемент <code>div</code> на текущей странице пользователя. Однако, если сессия истекает, сервер отправляет директиву на перенаправление, чтобы перенаправить пользователя на страницу входа. В этом случае jQuery заменяет элемент <code>div</code> содержимым страницы входа, что заставляет пользователя столкнуться с довольно редким зрелищем.

Как я могу обработать директиву перенаправления в Ajax-запросе с использованием jQuery 1.2.6?

5 ответ(ов)

0

Я люблю метод Тиммерза с небольшим добавлением лимона. Если вы получили contentType равным text/html, когда ожидали JSON, скорее всего, вас перенаправили. В моем случае я просто перезагружаю страницу, и она перенаправляется на страницу входа в систему. И не забудьте проверить, что статус jqXHR равен 200, что может показаться глупым, потому что вы же находитесь в функции обработки ошибок, верно? В противном случае законные случаи ошибок приведут к итеративной перезагрузке (упс).

$.ajax({
    error: function (jqXHR, timeout, message) {
        var contentType = jqXHR.getResponseHeader("Content-Type");
        if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
            // предположим, что наша сессия истекла - перезагрузим текущую страницу
            window.location.reload();
        }
    }
});

Если это помогло вам, не стесняйтесь оставить комментарий!

0

Вы можете использовать низкоуровневый вызов $.ajax() следующим образом:

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp - это объект XMLHttpRequest
    alert(xmlHttp.status);
  }
});

Для обработки редиректа попробуйте сделать следующее:

if (xmlHttp.status != 200) {
  top.location.href = '/some/other/page';
}

Этот код отправляет AJAX-запрос к вашему серверному компоненту и затем проверяет статус ответа. Если статус не равен 200, вы можете перенаправить пользователя на другую страницу. Не забудьте заменить '/some/other/page' на нужный вам URL.

0

Я хотел бы поделиться своим подходом, который может помочь кому-то из вас:

Я, по сути, включил модуль JavaScript, который обрабатывает аутентификацию, например, отображает имя пользователя и, в данном случае, выполняет перенаправление на страницу входа.

Мой сценарий: у нас в сети имеется сервер ISA, который перехватывает все запросы и ответствует статусом 302 с заголовком location на нашу страницу входа.

В моем модуле JavaScript мой первоначальный подход выглядел так:

$(document).ajaxComplete(function(e, xhr, settings){
    if(xhr.status === 302){
        // проверяем заголовок location и выполняем перенаправление...
    }
});

Проблема заключается в том, что браузер сам обрабатывает перенаправление, из-за чего мой коллбэк ajaxComplete никогда не вызывался, и вместо этого я получал ответ уже перенаправленной страницы входа, который, очевидно, имел статус 200. Проблема: как определить, является ли этот успешный 200 ответ вашей настоящей страницей входа или же просто какой-то другой произвольной страницей??

Решение

Так как я не смог захватить ответы на перенаправления 302, я добавил заголовок LoginPage на свою страницу входа, который содержал URL самой страницы входа. В модуле я теперь слушаю этот заголовок и выполняю перенаправление:

if(xhr.status === 200){
    var loginPageRedirectHeader = xhr.getResponseHeader("LoginPage");
    if(loginPageRedirectHeader && loginPageRedirectHeader !== ""){
        window.location.replace(loginPageRedirectHeader);
    }
}

...и это работает прекрасно 😃. Возможно, вам будет интересно, почему я включил URL в заголовок LoginPage... в основном, потому что я не нашел способа определить URL GET, который является результатом автоматического перенаправления из объекта xhr...

0

Я решил эту проблему следующим образом:

Я добавил middleware для обработки ответа. Если это редирект для AJAX-запроса, я изменяю ответ на обычный ответ с URL-адресом редиректа.

class AjaxRedirect(object):
    def process_response(self, request, response):
        if request.is_ajax():
            if isinstance(response, HttpResponseRedirect):
                r = HttpResponse(json.dumps({'redirect': response['Location']}))
                return r
        return response

После этого в ajaxComplete, если ответ содержит редирект, это значит, что нужно обновить локейшн браузера.

$('body').ajaxComplete(function (e, xhr, settings) {
   if (xhr.status == 200) {
       var redirect = null;
       try {
           redirect = $.parseJSON(xhr.responseText).redirect;
           if (redirect) {
               window.location.href = redirect.replace(/\?.*$/, "?next=" + window.location.pathname);
           }
       } catch (e) {
           return;
       }
   }
});

Таким образом, эта реализация позволяет корректно обрабатывать редиректы в AJAX-запросах.

0

У меня есть простое решение, которое работает для меня и не требует изменений на стороне сервера... просто добавьте щепотку мускатного ореха...

$(document).ready(function ()
{
    $(document).ajaxSend(
    function(event, request, settings)
    {
        var intercepted_success = settings.success;
        settings.success = function(a, b, c) 
        {  
            if (request.responseText.indexOf("<html>") > -1)
                window.location = window.location;
            else
                intercepted_success(a, b, c);
        };
    });
});

Я проверяю наличие тега <html>, но вы можете заменить indexOf на поиск любой другой уникальной строки, которая присутствует на вашей странице входа.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь