Имеет ли значение код состояния HTTP 0?

91

Похоже, что когда вы делаете XMLHttpRequest из сценария в браузере, если браузер настроен на работу в автономном режиме или если сетевой кабель выдернут, запрос завершается с ошибкой и со статусом = 0. 0 не входит в список допустимых. Коды состояния HTTP.

Что означает код состояния 0? Означает ли это одно и то же во всех браузерах и для всех клиентских утилит HTTP? Является ли это частью спецификации HTTP или какой-либо другой спецификации протокола? Похоже, это означает, что HTTP-запрос не может быть выполнен вообще, возможно, потому что адрес сервера не может быть разрешен.

Какое сообщение об ошибке следует показать пользователю? «Либо вы не подключены к Интернету, либо на веб-сайте возникли проблемы, либо в адресе может быть опечатка»?

Я должен добавить к этому, что я вижу поведение в FireFox, когда установлено значение «Работа в автономном режиме», но не в Microsoft Internet Explorer, когда установлено значение «Работа в автономном режиме». В IE пользователь получает диалоговое окно с возможностью выхода в Интернет. FireFox не уведомляет пользователя перед возвратом ошибки.

Я прошу это в ответ на просьбу «показать лучшее сообщение об ошибке». То, что делает Internet Explorer, хорошо. Он сообщает пользователю, что вызывает проблему, и дает ему возможность исправить это. Чтобы предоставить эквивалентный UX с FireFox, мне нужно определить причину проблемы и проинформировать пользователя. Итак, что в целом я могу вывести из статуса 0? Имеет ли он универсальное значение или мне ничего не говорит?

Марк Латтон
источник
См. Этот вопрос, посвященный той же теме: stackoverflow.com/questions/872206/…
Скотт Стаффорд
3
Я считаю, что это наиболее точный ответ: stackoverflow.com/a/14507670/700206
Whitneyland
Другой связанный пост - Что означает код статуса HTTP 0
RBT

Ответы:

155

Короткий ответ

Это не код ответа HTTP, но он задокументирован WhatWG как допустимое значение для атрибута состояния XMLHttpRequestответа или ответа Fetch.

Вообще говоря, это значение по умолчанию, используемое, когда нет реального кода состояния HTTP для сообщения и / или произошла ошибка при отправке запроса или получении ответа. Возможные сценарии, в которых это так, включают, но не ограничиваются:

  • Запрос еще не отправлен или был прерван.
  • Браузер все еще ожидает получения статуса ответа и заголовков.
  • Соединение разорвано во время запроса.
  • Время запроса истекло.
  • Запрос обнаружил бесконечный цикл перенаправления.
  • Браузер знает статус ответа, но вам не разрешен доступ к нему из-за ограничений безопасности, связанных с политикой одинакового происхождения .

Длинный ответ

Во-первых, повторюсь: 0 - это не код состояния HTTP. Их полный список содержится в RFC 7231, раздел 6.1 , без 0, а во введении к разделу 6 четко указано, что

Элемент status-code представляет собой трехзначный целочисленный код.

которого 0 нет.

Однако .statusзадокументировано значение 0 в качестве значения атрибута объекта XMLHttpRequest, хотя отследить все важные детали несколько сложно. Мы начинаем с https://xhr.spec.whatwg.org/#the-status-attribute , документируя .statusатрибут, в котором просто говорится:

statusАтрибут должен вернуть ответ «сек статуса .

Это может показаться бессмысленным и тавтологическим, но на самом деле здесь есть информация! Помните, что в этой документации здесь говорится об .responseатрибуте XMLHttpRequest, а не об ответе, поэтому это говорит нам, что определение статуса объекта XHR отложено до определения статуса ответа в спецификации Fetch.

Но что за объект ответа? Что, если мы еще не получили ответа? Встроенная ссылка на слово «ответ» ведет нас на https://xhr.spec.whatwg.org/#response , где объясняется:

XMLHttpRequestИмеет ассоциированный отклик. Если не указано иное, это сетевая ошибка .

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

Заглянув в стандарт Fetch , мы увидим, что:

Ошибка сети является ответом , чей статус всегда0

поэтому мы можем сразу сказать, что увидим состояние 0 для объекта XHR в любом из случаев, когда в спецификации XHR указано, что ответ должен быть установлен на ошибку сети. (Интересно, что это включает в себя случай, когда поток тела получает "ошибку", что, по словам спецификации Fetch, может произойти во время синтаксического анализа тела после получения статуса - поэтому теоретически я полагаю, что объект XHR может иметь свой статус установлено значение 200, затем при получении тела возникает ошибка нехватки памяти или что-то в этом роде, и поэтому его статус снова меняется на 0.)

Мы также отмечаем в стандарте Fetch, что существует пара других типов ответов, статус которых определен как 0, чье существование относится к запросам между источниками и политике одного источника:

Непрозрачный отфильтрованный ответ - это отфильтрованный ответ , состояние которого 0...

Отфильтрованный ответ с непрозрачным перенаправлением - это отфильтрованный ответ , состояние которого 0...

(различные другие подробности об этих двух типах ответов опущены).

Но помимо этого, существует также много случаев, когда алгоритм Fetch (а не спецификация XHR, которую мы уже рассмотрели) требует от браузера возврата сетевой ошибки! Действительно, фраза «вернуть сетевую ошибку» встречается в стандарте Fetch 40 раз . Я не буду пытаться перечислять здесь все 40, но отмечу, что они включают:

  • Случай, когда схема запроса не распознается (например, попытка отправить запрос на madeupscheme: //foobar.com)
  • Чудесно расплывчатая инструкция «Если есть сомнения, вернуть ошибку сети». в алгоритмах обработки URL-адресов ftp: // и file: //
  • Бесконечные перенаправления: «Если количество перенаправлений запроса равно двадцати, вернуть ошибку сети».
  • Куча проблем, связанных с CORS, таких как «Если повреждение ответа httpRequest не является« cors »и проверка политики ресурсов между источниками с запросом и ответом возвращает заблокированные, а затем возвращает сетевую ошибку».
  • Ошибки подключения: «Если подключение не удалось, вернуть ошибку сети».

Другими словами: когда что - то идет не так , другой , чем получить реальный HTTP код статуса ошибки вроде 500 или 400 с сервера, вы в конечном итоге с атрибутом состояния 0 на вашем объекте XHR или Fetch объект ответа в браузере. Количество возможных конкретных причин, перечисленных в спецификации, огромно.

Наконец: если по какой-то причине вас интересует история спецификации, обратите внимание, что этот ответ был полностью переписан в 2020 году, и что вас может заинтересовать предыдущая версия этого ответа , в которой, по сути, делались те же выводы из более старая (и намного более простая) спецификация W3 для XHR, до того, как они были заменены более современными и более сложными спецификациями WhatWG, к которым относится этот ответ.

Марк Эмери
источник
53

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

этот статус не задокументирован, но существует через вызовы ajax и makeRequest из gadget.io.

mnk
источник
4
Здравствуйте! Есть ли способ отличить неудачный («Нет сети») от отмененного запроса?
Ankur
2
Этот статус задокументирован как статус XmlHttpRequest. Конечно, это не статус http, но он задокументирован. w3.org/TR/XMLHttpRequest/#the-status-attribute Дополнительные сведения см. в ответе Марка Эмери.
Frédéric
4

Знай, что это старый пост. Но эти проблемы все еще существуют.

Вот некоторые из моих открытий по этому поводу, в общих чертах объясненных.

«Статус» 0 означает одно из трех, согласно спецификации XMLHttpRequest:

  • Ошибка разрешения имени DNS (например, когда вытащен сетевой штекер)

  • сервер не ответил (он же недоступен или не отвечает)

  • запрос был прерван из-за проблемы с CORS (прерывание выполняется пользовательским агентом и следует за ошибкой предварительной проверки OPTIONS).

Если вы хотите пойти дальше, погрузитесь в подробности XMLHttpRequest. Я предлагаю прочитать последовательность обновления состояния готовности ([0,1,2,3,4] - нормальная последовательность, [0,1,4] соответствует статусу 0, [0,1,2,4] означает отсутствие содержимого отправлено, что может быть ошибкой или нет). Вы также можете присоединить слушателей к xhr (onreadystatechange, onabort, onerror, ontimeout), чтобы выяснить детали.

Из спецификации (спецификация XHR Living ):

const unsigned short UNSENT = 0;
const unsigned short OPENED = 1;
const unsigned short HEADERS_RECEIVED = 2;
const unsigned short LOADING = 3;
const unsigned short DONE = 4;
Оботор
источник
1
Все возможные причины в вашем списке верны, но ваш список не является исчерпывающим. Например, вам не хватает тайм-аутов, бесконечных циклов перенаправления и других причин, подробно описанных в моем ответе . Однако указатель на новую живую спецификацию XHR полезен; Я должен обновить свой ответ, указав это вместо старой спецификации W3.
Марк Эмери
0

Начиная с iOS 9, вам необходимо добавить «Настройки безопасности транспорта приложений» в файл info.plist и разрешить «Разрешить произвольные нагрузки» перед отправкой запроса к незащищенной веб-службе HTTP. У меня была эта проблема в одном из моих приложений.

Нирав
источник
-1

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

  1. Перед завершением запроса ajax пользователь перешел на другую страницу.
  2. Запрос Ajax имеет тайм-аут.
  3. Сервер не может вернуть ответ.
Винаяк
источник