Что происходит, когда запрос AJAX получает ответ "302 Moved"?

Я пытаюсь AJAXify старую форму сайта без изменения конца. Первоначально бэкэнд ответил с переадресацией "302 Moved" на страницу "спасибо" после получения формы.

Теперь, когда я пытаюсь отправить форму с помощью вызова jQuery $.ajax, данные формы отправляются успешно, но перенаправление "302 Moved", похоже, отменяется браузером, а jQuery не знает, что происходит.

Моя проблема в том, что независимо от того, что происходит, вызов $.ajax возвращается с ошибкой и статусом = 0, поэтому у меня нет возможности различать успешную отправку и ошибку.

Есть ли способ предотвратить попытку браузера выполнить перенаправление или, по крайней мере, вернуть правильные коды ответов? (Я использую Chrome.)

Ответы

Ответ 1

Я думаю, что нет, вы не можете сделать это, не изменяя backend. Вы должны изменить заголовок ответа, чтобы Ajax знал/понимал, что делать. Если вы сделали перенаправление, вам нужно изменить заголовок, потому что ответ на вызов Ajax этого не сделает.

Ответ 2

Может ли это привести вас в правильном направлении?

$.ajax({
    type: "GET",
    url: url,
    data: data,
    complete: function(e, xhr, settings){
       if(e.status === 200){
            console.log(e.responseText);
       }else{
            console.log("error");
       }
   }
   });

Ответ 3

У вашего backend-приложения возможно относительное перенаправление, которое может каким-то образом не обрабатываться jquery ajax. Заголовок местоположения не будет включать имя домена в этой ситуации, только относительный путь. Для некоторых (неясно для меня;)) причин, по которым это может вызвать те же проблемы с политикой происхождения. Что смешно, изменение перенаправления на абсолютный путь должно решить проблему. Протестировано на jQuery 1.11.1.

Использование кода для описания:

Теоретический вызов ajax:

$.ajax({
    'url': '/your-url',
    'method': 'post',
    'data': form.serialize()
}).done(function(data) {
    // something
}).fail(function(jqXHR, textStatus, errorThrown) {
    // another something
});

Итак, в контроллере your/url у вас может быть что-то похожее на:

return $this->response->redirect('//same.domain/path');

или

return $this->response->redirect('/path');

Первая работа. Второй нет.

Так?

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

Ответ 4

Код Ajax будет выглядеть так:

$.ajax({
'url': '/your-url',
'method': 'post',
'data': form.serialize()
}).done(function(data) {
    // something
  }).fail(function(jqXHR, textStatus, errorThrown) {
if (jqXHR.getResponseHeader('Location') != null)
{ 
 window.Location= jqXHR.getResponseHeader('Location');
 }
 // other conditions in failure situation.
});

Ответ 5

Проверьте форму add {{csrf_field()}}. Это вызвано тем, что форма передается без токена.