JSON AJAX POST не перенаправляет браузер на 303 [дубликат]

Сначала проверьте ваше соединение.

Затем, если вы хотите получить точное значение из базы данных, тогда вы должны написать:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName =`$usernam`");

Или вы хотите получить LIKE, то вы должны написать:

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'");
1188
задан John Slegers 22 January 2016 в 21:21
поделиться

30 ответов

Решение, которое в итоге было реализовано, состояло в том, чтобы использовать оболочку для функции обратного вызова вызова Ajax и в этой проверке обертки для существования определенного элемента в возвращаемом фрагменте HTML. Если элемент был найден, оболочка выполнила перенаправление. В противном случае обертка переадресовала вызов фактической функции обратного вызова.

Например, наша оберточная функция была чем-то вроде:

function cbWrapper(data, funct){
    if($("#myForm", data).length > 0)
        top.location.href="login.htm";//redirection
    else
        funct(data);
}

Затем при создании Ajax-вызова мы использовали что-то вроде:

$.post("myAjaxHandler", 
       {
        param1: foo,
        param2: bar
       },
       function(data){
           cbWrapper(data, myActualCB);
       }, 
       "html"
);

работал для нас, потому что все вызовы Ajax всегда возвращают HTML внутри элемента DIV, который мы используем для замены части страницы. Кроме того, нам нужно было перенаправить на страницу входа.

86
ответ дан radbyx 26 August 2018 в 06:53
поделиться

Я решил эту проблему:

  1. Добавление настраиваемого заголовка в ответ:
    public ActionResult Index(){
        if (!HttpContext.User.Identity.IsAuthenticated)
        {
            HttpContext.Response.AddHeader("REQUIRES_AUTH","1");
        }
        return View();
    }
    
  2. Связывание функции JavaScript с ajaxSuccess и проверить, существует ли заголовок:
    $(document).ajaxSuccess(function(event, request, settings) {
        if (request.getResponseHeader('REQUIRES_AUTH') === '1') {
           window.location = '/';
        }
    });
    
214
ответ дан 5 revs, 4 users 77%SuperG 26 August 2018 в 06:53
поделиться
5
ответ дан Ali Adlavaran 26 August 2018 в 06:53
поделиться

У меня была эта проблема в приложении django, с которым я возился (отказ от ответственности: я возился, чтобы учиться, и я никоим образом не специалист). То, что я хотел сделать, это использовать jQuery ajax для отправки запроса DELETE на ресурс, удалить его на стороне сервера, а затем отправить перенаправление обратно (в основном) на главную страницу. Когда я отправил HttpResponseRedirect('/the-redirect/') из скрипта python, метод ajax jQuery получал 200 вместо 302. Таким образом, я сделал, чтобы отправить ответ 300 с помощью:

response = HttpResponse(status='300')
response['Location'] = '/the-redirect/' 
return  response

Затем я отправил / обработал запрос на клиенте с jQuery.ajax, например:

<button onclick="*the-jquery*">Delete</button>

where *the-jquery* =
$.ajax({ 
  type: 'DELETE', 
  url: '/resource-url/', 
  complete: function(jqxhr){ 
    window.location = jqxhr.getResponseHeader('Location'); 
  } 
});

Возможно, использование 300 не является «правильным», но по крайней мере оно работает так, как я этого хотел.

PS: это была огромная боль для редактирования на мобильной версии SO. Глупый интернет-провайдер подал запрос на отмену моего обслуживания, когда я закончил с моим ответом!

4
ответ дан Benny Jobigan 26 August 2018 в 06:53
поделиться

Я просто хотел защелкнуться на любые запросы ajax для всей страницы. @SuperG заставил меня начать. Вот что я закончил с:

// redirect ajax requests that are redirected, not found (404), or forbidden (403.)
$('body').bind('ajaxComplete', function(event,request,settings){
        switch(request.status) {
            case 301: case 404: case 403:                    
                window.location.replace("http://mysite.tld/login");
                break;
        }
});

Я хотел специально проверить определенные коды состояния http, чтобы основать мое решение. Однако вы можете просто привязать ajaxError к чему-то другому, кроме успеха (возможно, только 200)? Я мог бы просто написать:

$('body').bind('ajaxError', function(event,request,settings){
    window.location.replace("http://mysite.tld/login");
}
5
ответ дан Bretticus 26 August 2018 в 06:53
поделиться

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

$.ajax(
   error:  function (jqXHR, timeout, message) {
    var contentType = jqXHR.getResponseHeader("Content-Type");
    if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {
        // assume that our login has expired - reload our current page
        window.location.reload();
    }

});
60
ответ дан BrianY 26 August 2018 в 06:53
поделиться

Позвольте мне просто повторить проблему, описанную @Steg

. У меня была аналогичная проблема с вашей. Я выполняю запрос ajax, который имеет 2 возможных ответа: один, который перенаправляет браузер на новую страницу и заменяет существующую HTML-форму на текущей странице новым.

ИМХО это является реальной проблемой и должен быть официально распространен на существующие HTTP-стандарты.

Я считаю, что новым стандартом Http будет использоваться новый код состояния. значение: в настоящее время 301/302 сообщает браузеру перейти и получить содержимое этого запроса к новому location.

В расширенном стандарте он скажет, что если ответ status: 308 (просто пример), браузер должен перенаправить главную страницу на предоставленную location.

Это сказано; Я склонен уже имитировать это поведение future , и поэтому, когда необходим document.redirect, я отвечаю на сервер как:

status: 204 No Content
x-status: 308 Document Redirect
x-location: /login.html

Когда JS получает " status: 204 ", он проверяет существование заголовка x-status: 308 и делает document.redirect на странице, представленной в заголовке location.

Это имеет для вас какое-то значение?

4
ответ дан Chaim Klar 26 August 2018 в 06:53
поделиться

Я думаю, что лучший способ справиться с этим - использовать существующие коды ответа HTTP-протокола, в частности 401 Unauthorized.

Вот как я его решил:

  1. Сторона сервера: если сеанс истекает, а запрос - ajax. отправьте заголовок кода 401 ответа
  2. Сторона клиента: привязка к событиям ajax
    $('body').bind('ajaxSuccess',function(event,request,settings){
    if (401 == request.status){
        window.location = '/users/login';
    }
    }).bind('ajaxError',function(event,request,settings){
    if (401 == request.status){
        window.location = '/users/login';
    }
    });
    

IMO это более общий и вы не пишете новые пользовательские спецификации / заголовок. Вам также не нужно изменять какие-либо из ваших существующих вызовов ajax.

Изменить: в комментарии @ Rob ниже, 401 (код состояния HTTP для ошибок аутентификации) должен быть индикатором. См. 403 Запрещенные vs 401 Неавторизованные HTTP-ответы для более подробной информации. При этом некоторые веб-фреймворки используют 403 для ошибок аутентификации и авторизации, поэтому соответствующим образом адаптируйте их. Спасибо, Роб.

27
ответ дан Community 26 August 2018 в 06:53
поделиться

Вы также можете подключить прототип отправки XMLHttpRequest. Это будет работать для всех отправлений (jQuery / dojo / etc) с помощью одного обработчика.

Я написал этот код для обработки ошибки на 500 страниц с истекшим сроком действия, но он должен работать так же, как и ловушку перенаправления 200. Готов к записи wikipedia в XMLHttpRequest onreadystatechange о значении readyState.

// Hook XMLHttpRequest
var oldXMLHttpRequestSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.send = function() {
  //console.dir( this );

  this.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 500 && this.responseText.indexOf("Expired") != -1) {
      try {
        document.documentElement.innerHTML = this.responseText;
      } catch(error) {
        // IE makes document.documentElement read only
        document.body.innerHTML = this.responseText;
      }
    }
  };

  oldXMLHttpRequestSend.apply(this, arguments);
}
4
ответ дан Curtis Yallop 26 August 2018 в 06:53
поделиться

У меня есть рабочий solulion, используя ответы от @John и @Arpad link и @RobWinch link

Я использую Spring Security 3.2.9 и jQuery 1.10.2.

Расширить класс Spring, чтобы вызвать ответ 4XX только из запросов AJAX:

public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    public CustomLoginUrlAuthenticationEntryPoint(final String loginFormUrl) {
        super(loginFormUrl);
    }

    // For AJAX requests for user that isn't logged in, need to return 403 status.
    // For normal requests, Spring does a (302) redirect to login.jsp which the browser handles normally.
    @Override
    public void commence(final HttpServletRequest request,
                         final HttpServletResponse response,
                         final AuthenticationException authException)
            throws IOException, ServletException {
        if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
        } else {
            super.commence(request, response, authException);
        }
    }
}

applicationContext-security.xml

  <security:http auto-config="false" use-expressions="true" entry-point-ref="customAuthEntryPoint" >
    <security:form-login login-page='/login.jsp' default-target-url='/index.jsp'                             
                         authentication-failure-url="/login.jsp?error=true"
                         />    
    <security:access-denied-handler error-page="/errorPage.jsp"/> 
    <security:logout logout-success-url="/login.jsp?logout" />
...
    <bean id="customAuthEntryPoint" class="com.myapp.utils.CustomLoginUrlAuthenticationEntryPoint" scope="singleton">
        <constructor-arg value="/login.jsp" />
    </bean>
...
<bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
    <property name="requestMatcher">
      <bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
        <constructor-arg>
          <bean class="org.springframework.security.web.util.matcher.MediaTypeRequestMatcher">
            <constructor-arg>
              <bean class="org.springframework.web.accept.HeaderContentNegotiationStrategy"/>
            </constructor-arg>
            <constructor-arg value="#{T(org.springframework.http.MediaType).APPLICATION_JSON}"/>
            <property name="useEquals" value="true"/>
          </bean>
        </constructor-arg>
      </bean>
    </property>
</bean>

В моих JSP добавьте глобальный обработчик ошибок AJAX, как показано здесь здесь

  $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
      if ( jqxhr.status === 403 ) {
          window.location = "login.jsp";
      } else {
          if(thrownError != null) {
              alert(thrownError);
          } else {
              alert("error");
          }
      }
  });

. Также удалите существующие обработчики ошибок из вызовов AJAX в JSP-страницах:

        var str = $("#viewForm").serialize();
        $.ajax({
            url: "get_mongoDB_doc_versions.do",
            type: "post",
            data: str,
            cache: false,
            async: false,
            dataType: "json",
            success: function(data) { ... },
//            error: function (jqXHR, textStatus, errorStr) {
//                 if(textStatus != null)
//                     alert(textStatus);
//                 else if(errorStr != null)
//                     alert(errorStr);
//                 else
//                     alert("error");
//            }
        });

Надеюсь, что это поможет другим.

Update1 Я обнаружил, что мне нужно добавить параметр (always-use-default-target = "true") в конфигурацию формы входа. Это было необходимо, так как после запроса AJAX перенаправляется на страницу входа (из-за истекшего сеанса), Spring запоминает предыдущий запрос AJAX и автоматически перенаправляет его после входа в систему. Это приведет к отображению возвращаемого JSON на странице браузера. Конечно, не то, что я хочу.

Update2 Вместо использования always-use-default-target="true" используйте пример @RobWinch блокировки запросов AJAX из requstCache. Это позволяет нормальным ссылкам перенаправляться на исходную цель после входа в систему, но AJAX переходит на домашнюю страницу после входа в систему.

0
ответ дан Darren Parker 26 August 2018 в 06:53
поделиться

Никакие браузеры не обрабатывают 301 и 302 ответов правильно. И на самом деле стандарт даже говорит, что они должны обрабатывать их «прозрачно», что является МАССИВНОЙ головной болью для поставщиков библиотеки Ajax. В Ra-Ajax мы были вынуждены использовать HTTP-код ответа HTTP 278 (только некоторый «неиспользуемый» код успеха) для обработки прозрачных переадресаций с сервера ...

Это действительно раздражает я, и если у кого-то здесь есть «pull» в W3C, я был бы признателен, что вы могли бы сообщить W3C знать , что нам действительно нужно обрабатывать 301 и 302 коды ...! ;)

106
ответ дан Gone Coding 26 August 2018 в 06:53
поделиться

Объединив то, что сказал Владимир Прудников и Томас Хансен:

  • Измените свой серверный код, чтобы определить, является ли это XHR. Если это так, установите ответный код перенаправления на 278. В django:
   if request.is_ajax():
      response.status_code = 278

Это делает браузер успешным ответом на ответ.

  • В своем JS убедитесь, что представление формы через Ajax, проверьте код ответа и при необходимости перенаправите:
$('#my-form').submit(function(event){ 

  event.preventDefault();   
  var options = {
    url: $(this).attr('action'),
    type: 'POST',
    complete: function(response, textStatus) {    
      if (response.status == 278) { 
        window.location = response.getResponseHeader('Location')
      }
      else { ... your code here ... } 
    },
    data: $(this).serialize(),   
  };   
  $.ajax(options); 
});
16
ответ дан Graham King 26 August 2018 в 06:53
поделиться

У меня не было никакого успеха в решении заголовка - они никогда не были получены в моем методе ajaxSuccess / ajaxComplete. Я использовал ответ Штега с пользовательским ответом, но я немного изменил сторону JS. Я настраиваю метод, который я вызываю в каждой функции, поэтому я могу использовать стандартные методы $.get и $.post.

function handleAjaxResponse(data, callback) {
    //Try to convert and parse object
    try {
        if (jQuery.type(data) === "string") {
            data = jQuery.parseJSON(data);
        }
        if (data.error) {
            if (data.error == 'login') {
                window.location.reload();
                return;
            }
            else if (data.error.length > 0) {
                alert(data.error);
                return;
            }
        }
    }
    catch(ex) { }

    if (callback) {
        callback(data);
    }
}

Пример использования в нем ...

function submitAjaxForm(form, url, action) {
    //Lock form
    form.find('.ajax-submit').hide();
    form.find('.loader').show();

    $.post(url, form.serialize(), function (d) {
        //Unlock form
        form.find('.ajax-submit').show();
        form.find('.loader').hide();

        handleAjaxResponse(d, function (data) {
            // ... more code for if auth passes ...
        });
    });
    return false;
}
5
ответ дан jocull 26 August 2018 в 06:53
поделиться

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

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

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

В моем модуле JavaScript мой первоначальный подход был чем-то вроде

$(document).ajaxComplete(function(e, xhr, settings){
    if(xhr.status === 302){
        //check for location header and redirect...
    }
});

. Проблема (как уже упоминалось выше) заключается в том, что браузер обрабатывает перенаправление самостоятельно, поэтому мой обратный вызов ajaxComplete никогда не вызывался, но вместо этого я получил ответ из уже перенаправленной страницы входа, которая, очевидно, была status 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 ...

32
ответ дан Juri 26 August 2018 в 06:53
поделиться

Если вы также хотите передать значения, вы также можете установить переменные сеанса и получить доступ. Например: в jsp вы можете написать

<% HttpSession ses = request.getSession(true);
   String temp=request.getAttribute("what_you_defined"); %>

. Затем вы можете сохранить это значение темпа в своем javascript переменная и игра вокруг

5
ответ дан karthik339 26 August 2018 в 06:53
поделиться

Другое решение, которое я нашел (особенно полезно, если вы хотите установить глобальное поведение), заключается в использовании метода $.ajaxsetup() вместе с свойством statusCode . Как и другие указатели, не используйте код статуса перенаправления (3xx), вместо этого используйте код статуса 4xx и обрабатываете клиентскую сторону с переадресацией.

$.ajaxSetup({ 
  statusCode : {
    400 : function () {
      window.location = "/";
    }
  }
});

Замените 400 кодом состояния вы хотите справиться. Как уже упоминалось 401 Unauthorized, может быть хорошей идеей. Я использую 400, поскольку он очень неспецифичен, и я могу использовать 401 для более конкретных случаев (например, неправильные учетные данные). Поэтому вместо перенаправления непосредственно ваш backend должен возвращать код ошибки 4xx, когда время ожидания сеанса и вы обрабатываете клиентскую часть перенаправления. Работает идеально для меня даже с фреймворками, такими как backbone.js

17
ответ дан morten.c 26 August 2018 в 06:53
поделиться

Хотя ответы, похоже, работают для людей, если вы используете Spring Security, я нашел расширение LoginUrlAuthenticationEntryPoint и добавление определенного кода для более эффективного управления AJAX. Большинство примеров перехватывают все перенаправляют не только неудачи аутентификации. Это было нежелательно для проекта, над которым я работаю. Возможно, вам также потребуется расширить ExceptionTranslationFilter и переопределить метод sendStartAuthentication, чтобы удалить шаг кэширования, если вы не хотите, чтобы сбойный запрос AJAX был кеширован.

Пример AjaxAwareAuthenticationEntryPoint:

public class AjaxAwareAuthenticationEntryPoint extends
    LoginUrlAuthenticationEntryPoint {

    public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
        super(loginUrl);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        if (isAjax(request)) {
            response.sendError(HttpStatus.UNAUTHORIZED.value(), "Please re-authenticate yourself");
        } else {
        super.commence(request, response, authException);
        }
    }

    public static boolean isAjax(HttpServletRequest request) {
        return request != null && "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }
}

Источники: 1 , 2

18
ответ дан MRFrhn 26 August 2018 в 06:53
поделиться

Я решил это, поставив следующее на моей странице login.php.

<script type="text/javascript">
    if (top.location.href.indexOf('login.php') == -1) {
        top.location.href = '/login.php';
    }
</script>
11
ответ дан Paul Richards 26 August 2018 в 06:53
поделиться

Попробуйте

    $(document).ready(function () {
        if ($("#site").length > 0) {
            window.location = "<%= Url.Content("~") %>" + "Login/LogOn";
        }
    });

Поместите его на страницу входа. Если он был загружен в div на главной странице, он будет перенаправлен до страницы входа. «#site» - это идентификатор div, который находится на всех страницах, кроме страницы входа.

12
ответ дан podeig 26 August 2018 в 06:53
поделиться
    <script>
    function showValues() {
        var str = $("form").serialize();
        $.post('loginUser.html', 
        str,
        function(responseText, responseStatus, responseXML){
            if(responseStatus=="success"){
                window.location= "adminIndex.html";
            }
        });     
    }
</script>
12
ответ дан Priyanka 26 August 2018 в 06:53
поделиться

Эта проблема может возникнуть при использовании метода ASP.NET MVC RedirectToAction. Чтобы предотвратить отображение формы в div, вы можете просто сделать какой-то фильтр ответа ajax для входящих ответов с $ .ajaxSetup. Если ответ содержит перенаправление MVC, вы можете оценить это выражение на стороне JS. Пример кода для JS ниже:

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data && typeof data == "string") {
            if (data.indexOf('window.location') > -1) {
                eval(data);
            }
        }
        return data;
    }
});

Если данные: "window.location = '/ Acount / Login'" выше фильтр поймает это и оценит, чтобы сделать перенаправление вместо того, чтобы отображать данные.

17
ответ дан Przemek Marcinkiewicz 26 August 2018 в 06:53
поделиться

Большинство данных решений используют обходной путь, используя дополнительный заголовок или неадекватный HTTP-код. Эти решения, скорее всего, будут работать, но немного «взломать». Я придумал другое решение.

Мы используем WIF, который настроен на перенаправление (passiveRedirectEnabled = "true") на ответ 401. Переадресация полезна при обращении с обычными запросами, но не будет работать для AJAX-запросов (поскольку браузеры не будут выполнять 302 / переадресацию).

Используя следующий код в вашем global.asax, вы можете отключить перенаправление для запросов AJAX:

    void WSFederationAuthenticationModule_AuthorizationFailed(object sender, AuthorizationFailedEventArgs e)
    {
        string requestedWithHeader = HttpContext.Current.Request.Headers["X-Requested-With"];

        if (!string.IsNullOrEmpty(requestedWithHeader) && requestedWithHeader.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase))
        {
            e.RedirectToIdentityProvider = false;
        }
    }

Это позволяет вам возвращать 401 ответа на запросы AJAX, которые могут быть у вашего javascript затем выполните перезагрузку страницы. Перезагрузка страницы вызовет 401, которые будут обрабатываться WIF (и WIF перенаправит пользователя на страницу входа в систему).

Пример javascript для обработки ошибок 401:

$(document).ajaxError(function (event, jqxhr, settings, exception) {

    if (jqxhr.status == 401) { //Forbidden, go to login
        //Use a reload, WIF will redirect to Login
        location.reload(true);
    }
});
17
ответ дан Rob 26 August 2018 в 06:53
поделиться

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

После того, как я снова начал копаться, я бросил этот подход и использовал JSON . В этом случае все ответы на запросы ajax имеют код состояния 200, а тело ответа содержит объект JSON, который построен на сервере. Javascript на клиенте может затем использовать объект JSON, чтобы решить, что ему нужно делать.

У меня была аналогичная проблема с вашей. Я выполняю запрос ajax, который имеет 2 возможных ответа: один, который перенаправляет браузер на новую страницу и заменяет существующую HTML-форму на текущей странице новой. Код jquery для этого выглядит примерно так:

$.ajax({
    type: "POST",
    url: reqUrl,
    data: reqBody,
    dataType: "json",
    success: function(data, textStatus) {
        if (data.redirect) {
            // data.redirect contains the string URL to redirect to
            window.location.href = data.redirect;
        }
        else {
            // data.form contains the HTML for the replacement form
            $("#myform").replaceWith(data.form);
        }
    }
});

Объект «данные» объекта JSON построен на сервере, чтобы иметь 2 члена: data.redirect и data.form. Я нашел этот подход намного лучше.

634
ответ дан Steg 26 August 2018 в 06:53
поделиться

Используйте низкоуровневый вызов $.ajax():

$.ajax({
  url: "/yourservlet",
  data: { },
  complete: function(xmlHttp) {
    // xmlHttp is a XMLHttpRquest object
    alert(xmlHttp.status);
  }
});

Попробуйте это для перенаправления:

if (xmlHttp.code != 200) {
  top.location.href = '/some/other/page';
}
46
ответ дан Till 26 August 2018 в 06:53
поделиться

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

$(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 для поиска любой уникальной строки на вашей странице входа ...

15
ответ дан Timmerz 26 August 2018 в 06:53
поделиться

Некоторые могут найти ниже полезное:

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

Это то, что я сделал:

В любом запросе Ajax мой сервер вернет ответ Json 200 «НЕОБХОДИМОСТЬ АВТОРИЗАЦИИ» (если клиент должен пройти аутентификацию).

Простой пример в Java (на стороне сервера):

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private final Logger m_logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    public static final String COOKIE_NAME = "token_cookie"; 

    @Override
    public void filter(ContainerRequestContext context) throws IOException {        
        // Check if it has a cookie.
        try {
            Map<String, Cookie> cookies = context.getCookies();

            if (!cookies.containsKey(COOKIE_NAME)) {
                m_logger.debug("No cookie set - redirect to login page");
                throw new AuthenticationException();
            }
        }
        catch (AuthenticationException e) {
            context.abortWith(Response.ok("\"NEED TO AUTHENTICATE\"").type("json/application").build());
        }
    }
}

В моем Javascript я добавил следующий код:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var originalSuccess = options.success;

    options.success = function(data) {
        if (data == "NEED TO AUTHENTICATE") {
            window.location.replace("/login.html");
        }
        else {
            originalSuccess(data);
        }
    };      
});

И это все.

7
ответ дан Tomer 26 August 2018 в 06:53
поделиться

в сервлете вы должны поместить response.setStatus(response.SC_MOVED_PERMANENTLY);, чтобы отправить статус xmlHttp '301', необходимый для перенаправления ...

, а в функции $ .ajax вы не должны использовать .toString() function ..., just

if (xmlHttp.status == 301) { top.location.href = 'xxxx.jsp'; }

проблема в том, что она не очень гибкая, вы не можете решить, куда вы хотите перенаправить ..

перенаправление через сервлеты должно быть лучшим способом. но я все еще не могу найти правильный способ сделать это.

5
ответ дан user 26 August 2018 в 06:53
поделиться

Кроме того, вы, вероятно, захотите перенаправить пользователя к указанному в URL-адресе заголовков. Итак, это будет выглядеть так:

$.ajax({
    //.... other definition
    complete:function(xmlHttp){
        if(xmlHttp.status.toString()[0]=='3'){
        top.location.href = xmlHttp.getResponseHeader('Location');
    }
});

UPD: Opps. Иметь ту же задачу, но она не работает. Делать это. Я покажу вам решение, когда найду его.

1
ответ дан Vladimir Prudnikov 26 August 2018 в 06:53
поделиться
27
ответ дан Community 26 August 2018 в 06:53
поделиться

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

Добавить промежуточное программное обеспечение для обработки ответа, если оно является перенаправлением для запроса ajax, изменить ответ на нормальный ответ с URL-адресом перенаправления.

class AjaxRedirect(object):
  def process_response(self, request, response):
    if request.is_ajax():
      if type(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;
       }
   }
}
18
ответ дан MRFrhn 26 August 2018 в 06:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: