Запретить перенаправление Xmlhttprequest

Можно ли запретить браузеру следовать перенаправлениям при отправке XMLHttpRequest-s (то есть вернуть код состояния перенаправления и обработать его самостоятельно)?

6 ответов

Решение

Не соответствует стандарту W3C для объекта XMLHttpRequest (выделение добавлено):

Если ответ является перенаправлением HTTP:

Если источник URL, передаваемый заголовком Location, совпадает с источником источника XMLHttpRequest и перенаправление не нарушает меры предосторожности бесконечного цикла, прозрачно следуйте перенаправлению, соблюдая правила события запроса того же источника.

Они рассматривали это для будущего выпуска:

Эта спецификация не включает следующие функции, которые рассматриваются для будущей версии этой спецификации:

  • Свойство отключить следующие перенаправления;

но последняя спецификация больше не упоминает об этом.

Новый API Fetch поддерживает различные режимы обработки перенаправления: follow, error, а также manual, но я не могу найти способ просмотра нового URL или кода состояния, когда перенаправление было отменено. Вы можете просто остановить само перенаправление, и тогда оно будет выглядеть как ошибка (пустой ответ). Если это все, что вам нужно, вы можете идти. Также вы должны знать, что запросы, сделанные через этот API, еще не могут быть отменены. Они сейчас.

Что касается XMLHttpRequest, вы можете HEAD сервер и проверьте, изменился ли URL:

var http = new XMLHttpRequest();
http.open('HEAD', '/the/url');
http.onreadystatechange = function() {
    if (this.readyState === this.DONE) {
        console.log(this.responseURL);
    }
};
http.send();

Вы не получите код состояния, но найдете новый URL, не загрузив с него всю страницу.

Нет, вы не найдете никакого места в API, предоставляемом XMLHttpRequest, который позволяет вам переопределить его поведение по умолчанию следующего 301 или 302 автоматически.

Если клиент запускает IE в Windows, вы можете использовать WinHTTP вместо этого, чтобы установить параметр, предотвращающий такое поведение, но это очень ограничивающее решение.

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

Я расширил ответ пользователя, включив в него abort()вызов. Похоже, это не позволяет серверу отправлять слишком много данных, когда все, что вам нужно, - это URL-адрес перенаправления.

      var url = 'the url'
var http = new XMLHttpRequest();
http.open('GET', url);
http.onreadystatechange = function() {
    if (this.readyState === this.DONE) {
        console.log(this.responseURL)
        this.abort() // This seems to stop the response
    }
}
http.send()

В реальной жизни я заключил приведенный выше код в обещание, но это затруднило чтение кода.

Кроме того, я не понимаю, почему получение URL-адреса перенаправления должно быть таким сложным, но это вопрос для другого времени и места.

Невозможно обрабатывать перенаправление или статус 302 на стороне клиента, как указано в других комментариях. Однако вы можете предотвратить перенаправление. Для этого вы можете установить заголовок запроса "X-Requested-With" с помощью "XMLHttpRequest" xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); Это нужно делать после открытия, но перед отправкой. Пример ниже

let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
   if (this.readyState == 4 && this.status == 200) {
         reqObj.success(JSON.parse(this.responseText))
   } else if (this.status != 200) {
         reqObj.error(this.statusText)
   }
};
xhttp.open(reqObj.type, reqObj.url, reqObj.async);
xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhttp.send();
Другие вопросы по тегам