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

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

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

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

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

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

Ответ 1

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

Это не код ответа HTTP, но он документируется W3 как допустимое значение для атрибута status для XMLHttpRequest (и, следовательно, также для объекта jqXHR для пользователей jQuery).

Он охватывает всю последовательность возможных ситуаций, в которых нет реального HTTP-кода ответа, доступного для отчета, либо из-за того, что вы не отправили запрос, вы явно его прервали, страница выгрузилась, либо x пошла не так для одной из много возможных значений х.

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

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

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

который не является.

Тем не менее, 0 в качестве значения атрибута status объекта XMLHttpRequest документируется. Из документации по адресу http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute:

4.7.1 Атрибут состояния

Атрибут status должен вернуть результат выполнения следующих шагов:

  • Если состояние UNSENT или OPENED, верните 0.

  • Если флаг ошибки установлен, верните 0.

  • Возвращает код состояния HTTP.

Мы можем углубиться в спецификацию и выяснить, что означают эти условия для возврата 0. Из http://www.w3.org/TR/XMLHttpRequest/#states:

4.5. Состояния

...

UNSENT (числовое значение 0)

Объект был создан.

OPENED (числовое значение 1)

Метод open() успешно активирован. Во время этого состояния заголовки запросов могут быть установлены с помощью setRequestHeader(), и запрос может быть выполнен с использованием метода send().

...

Флаг ошибки указывает на какой-либо тип сетевой ошибки или завершение выборки. Он изначально не установлен.

Также важно отметить, что следующее возможное состояние после UNSENT и OPENED равно HEADERS_RECEIVED:

HEADERS_RECEIVED (числовое значение 2)

Все переадресации (если есть) были выполнены, и все HTTP-заголовки окончательного ответа были получены. Теперь доступно несколько элементов ответа объекта.

Объединяя все это, короткий ответ состоит в том, что 0 - это просто то, что возвращается атрибутом status объекта XMLHttpRequest, когда нет реального кода состояния для возврата, потому что либо:

  • Запрос еще не отправлен, или
  • Запрос отправлен, но заголовки ответа еще не получены или
  • Возникло одно из многих возможных обстоятельств, перечисленных в документах, которые вызвали установку "флага ошибки".

Хорошо, но какие ошибки могут привести к такому таинственному значению "флаг ошибки"? Если вы указали CTRL-F для "флага ошибки" в документации W3, вы обнаружите, что при отправке запроса он не будет отменен, и он только когда-либо будет установлен как часть алгоритма для "завершения запроса". Если вы ищете все места, в которых вызывается алгоритм, вы обнаружите, что это происходит, когда:

  • Запрос открывается (или повторно открывается) с помощью метода open()
  • Запрос на сбор мусора (например, при выходе из страницы)
  • Запрос прерывается с помощью метода abort()
  • Произошла ошибка запроса, которая может произойти при возникновении одной из следующих ситуаций:

    • Произошла сетевая ошибка, которая может произойти, если

      • Существует бесконечный цикл перенаправления
      • Есть/есть

        Ошибки DNS, ошибка согласования TLS или ошибка сетевого типа другого типа

      • Запрос был запросом CORS, и ответ не может быть общим.
    • Произошла ошибка прерывания, которая может произойти только в том случае, если

      Конечный пользователь отменяет запрос

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

    • Произошла ошибка времени ожидания, что означает, что достаточно разумно, чтобы

      timeout не равно 0, и с момента начала запроса количество миллисекунд, указанное timeout, прошло

Что касается XMLHttpRequest, это все.

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

Ответ 2

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

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

Ответ 4

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

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

"Статус" 0 означает одну из трех вещей, в соответствии с спецификацией XMLHttpRequest:

  • Не удалось разрешить имя имени dns (например, когда сетевой штекер вытащен)

  • сервер не ответил (a.k.a. недоступен или не соответствует)

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

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

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

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;

Ответ 5

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

Ответ 6

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

  • До завершения запроса ajax пользователь перешел на другую страницу.
  • Запрос Ajax имеет тайм-аут.
  • Сервер не может вернуть ответ.