Что это значит, когда HTTP-запрос возвращает код состояния 0?

131

Что это означает, когда сетевые вызовы JavaScript, такие как fetch или XMLHttpRequest, или любой другой тип сетевого запроса HTTP завершаются неудачно с кодом состояния HTTP 0?

Это не похоже на действительный код состояния HTTP, поскольку другие коды в спецификации HTTP состоят из трех цифр.

В качестве теста я попытался полностью отключить сеть. Это может быть не связано, но это привело к коду состояния 17003 (IIRC), который, как подсказывает беглый поиск, означает «сбой поиска на DNS-сервере».

Тот же код отлично работает в некоторых местах и ​​системах, однако в некоторых средах он не работает с кодом состояния 0 и не предоставляется responseText.

Это типичный HTTP POST для URL-адреса в Интернете. Это не связано с файлом: //, который, как я понимаю, может возвращать 0, указывая на успех в Firefox.

Майк Нельсон
источник
Может быть, из-за брандмауэра? На какой ОС работает ваше приложение?
шахкалпеш
Может быть полезно: stackoverflow.com/a/12622082/386579
shasi kanth 09
Связанное сообщение - Что означает код статуса HTTP 0
RBT
У меня была такая же проблема в Firefox и выяснили , что блокировка рекламы плагин предотвращает все запросы к URL - адресам , которые содержат словоbanner
Jan

Ответы:

56

Я считаю, что код ошибки указывает на то, что ответ был пустым (поскольку не были возвращены даже заголовки). Это означает, что соединение было принято, а затем корректно закрыто (TCP FIN). Есть несколько причин, которые могут вызвать это, но, судя по вашему описанию, наиболее вероятным виновником является какой-то брандмауэр.

Ник
источник
2
Думаю, вы, наверное, правы. (Хотя, как указывает @sleepycod, ожидается, что wininet.dll вернет некоторый код статуса в отсутствие реального кода статуса http.)
Майк Нельсон
1
Это не обязательно правильно. У меня была такая же проблема, но в моем случае запрос не был отправлен. Причина заключалась в том , что блокировка рекламы Firefox предотвращена запросы , чьи адреса содержат словоbanner
Jan
195

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

Фактически, status == 0 для неудачного запроса XmlHttpRequest следует рассматривать как неопределенную ошибку.

Фактическая спецификация W3C определяет условия, для которых здесь возвращается ноль: https://fetch.spec.whatwg.org/#concept-network-error

Как видно из спецификации (выборка или XmlHttpRequest), этот код может быть результатом ошибки, которая произошла еще до обращения к серверу.

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

  1. Запрос о незаконном перекрестном происхождении (см. CORS )
  2. Блокировка или фильтрация межсетевого экрана
  3. Сам запрос был отменен в коде
  4. Установленное расширение для браузера все портит

Для браузеров было бы полезно предоставлять подробные отчеты об ошибках для большего количества сценариев status == 0. Действительно, иногда status == 0 сопровождает полезное консольное сообщение, но в других случаях другой информации нет.

whitneyland
источник
4
Надстройка Firefox NoScript может отменить запрос XHR к ненадежным хостам.
Иван Солнцев
5
+1, все это верно, и «произошла какая-то ошибка» - это практическая интерпретация. Для людей, заинтересованных в исчерпывающем списке возможных причин, указанных в спецификации, я опубликовал разбивку на stackoverflow.com/a/26451773/1709587 .
Марк Эмери
1
Среди случаев, подробно описанных Марком Америкой, которые вызывают у меня больше всего проблем, - это дело Cors. Если ошибка приводит к тому, что ответ не проходит проверку cors, вы получите статус 0 вместо статуса http, поскольку, когда проверка cors завершается неудачно, ответ недоступен. Особенно неприятно при попытке обнаружить веб-api, находящийся на обслуживании и отвечающий на 503. Если этот api не соблюдает cors во время обслуживания, вы не сможете обнаружить 503, вы просто получите 0, что может быть вызвано множеством других вещи.
Frédéric
Проблема CORS, с которой я столкнулся: подумайте об использовании httpвместо того, httpsчтобы ваша страница была изначально загружена, httpи наоборот. Другие слова не выполняют ajax POSTчерез, httpsесли к вашей странице обращались через, httpи не выполняют ajax POSTчерез, httpесли ваша страница была изначально доступна через https.
Виктор Понамарев
Синхронные запросы
вызывают
35

Как бы то ни было, в зависимости от браузера, вызовы AJAX на основе jQuery будут вызывать ваш успешный обратный вызов с кодом состояния HTTP 0. Мы обнаружили, что код состояния "0" обычно означает, что пользователь перешел на другую страницу раньше. вызов AJAX завершен.

Не тот стек технологий, который вы используете, но, надеюсь, кому-то пригодится.

Кори Р. Кинг
источник
Да, люди, вероятно, часто сталкиваются с этой проблемой, поскольку у этой страницы было 10 000 просмотров.
Майк Нельсон
Или я должен сказать 25 000 просмотров?
Майк Нельсон
3
Это многого стоит: именно это и давало сбои в моих автоматических тестах. Большое спасибо!
alexfernandez
Проголосовали не потому, что это «» правильный ответ, а то, что происходило в моем случае.
Хуан Мендес
Это определенно происходит, но это не единственная причина, по которой вы увидите код ошибки == 0. Вы не можете предположить, что это просто пользователь, уйдя и, следовательно, отфильтруйте сообщения об ошибках этого типа.
wal
14

wininet.dll возвращает стандартные и нестандартные коды состояния, перечисленные ниже.

401 - Unauthorized file
403 - Forbidden file
404 - File Not Found
500 - some inclusion or functions may missed
200 - Completed

12002 - Server timeout
12029,12030, 12031 - dropped connections (either web server or DB server)
12152 - Connection closed by server.
13030 - StatusText properties are unavailable, and a query attempt throws an exception

Для кода состояния «ноль» вы пытаетесь выполнить запрос на локальной веб-странице, работающей на веб-сервере или без веб-сервера?

XMLHttpRequest status = 0 и XMLHttpRequest statusText = unknown могут помочь вам, если вы не запускаете свой скрипт на веб-сервере.

Кристоф Эбле
источник
Спасибо за коды. Нет, это не локальный запрос, это запрос к веб-серверу в Интернете от локально запущенного vbscript.
Майк Нельсон
6

Обходной путь: что мы в итоге сделали

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

  1. Мы по-прежнему записываем данные в текстовый файл на локальном жестком диске, как и раньше, с использованием HTA.

  2. Когда пользователь щелкает «отправить данные обратно на сервер», HTA считывает данные и записывает HTML-страницу, которая включает эти данные в виде острова данных XML (фактически с использованием блока сценария SCRIPT LANGUAGE = XML).

  3. HTA запускает ссылку на HTML-страницу в браузере.

  4. HTML-страница теперь содержит javascript, который отправляет данные на сервер (используя Microsoft.XMLHTTP).

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

Майк Нельсон
источник
Привет, я изучаю аналогичную проблему, которая возникает у клиента в производственной среде. Вы говорите, что проблема была вызвана брандмауэром. Вы случайно не помните, какой эффект был вызван брандмауэром или что брандмауэр сделал, чтобы вызвать это?
Ибрагим Наджар
5

Код ответа HTTP 0 указывает, что запрос AJAX был отменен.

Это может произойти либо из-за таймаута, либо из-за прерывания XHR, либо из-за того, что брандмауэр нарушает запрос. Тайм-аут является обычным явлением, это означает, что запрос не был выполнен в течение указанного времени. Прерывание XHR очень просто сделать ... вы действительно можете вызвать .abort () для объекта XMLHttpRequest, чтобы отменить вызов AJAX. ( Это хорошая практика для одностраничного приложения, если вы не хотите, чтобы вызовы AJAX возвращались и пытались ссылаться на объекты, которые были уничтожены. ) Как упоминалось в отмеченном ответе, брандмауэр также может отменить запрос и вызвать его 0 ответ.

XHR Abort: прерывание запросов Ajax с использованием jQuery

var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

Стоит отметить, что запуск метода .abort () для объекта XHR также вызовет обратный вызов ошибки. Если вы выполняете какую-либо обработку ошибок, которая анализирует эти объекты, вы быстро заметите, что прерванный XHR и тайм-аут XHR идентичны, но с jQuery textStatus, который передается в обратный вызов ошибки, будет «прерван» при прерывании. и происходит "таймаут" с таймаутом. Если вы используете Zepto (очень похожий на jQuery), errorType будет иметь значение «error» при прерывании и «timeout» при возникновении тайм-аута.

jQuery: error(jqXHR, textStatus, errorThrown);
Zepto:  error(xhr, errorType, error);
Кори Дэниэлсон
источник
4

Как подробно описано в этом ответе на этой странице , код состояния 0 означает, что запрос не удалось выполнить по какой-либо причине, а библиотека javascript интерпретировала сбой как код состояния 0.

Чтобы проверить это, вы можете сделать одно из следующих действий:

1) Используйте это расширение chrome, Requestly, чтобы перенаправить ваш URL-адрес из httpsверсии вашего URL- адреса в httpверсию, так как это вызовет ошибку безопасности смешанного содержимого и в конечном итоге сгенерирует код состояния 0. Преимущество этого подхода в том, что вы не используете Вам вообще не нужно менять приложение, и вы можете просто «переписать» свой URL-адрес, используя это расширение.

2) Измените код своего приложения, чтобы при необходимости перенаправить конечную точку на http версию вашего URL-адреса вместо httpsверсии (или наоборот). Если вы это сделаете, запрос не будет выполнен с кодом состояния 0.

Брэд Паркс
источник
1
«Использовать это расширение для Chrome» - расширение для Chrome? В приложении HTA?
Квентин
4
Хорошая точка зрения! Но большинство людей, прибывающих сюда, не попадают сюда за приложениями HTA. Они ищут в Google "javascript http status code 0" или что-то в этом роде и приходят сюда - так что я думаю, что HTA-часть этого вопроса имеет наименьшее значение в целом, и в конечном итоге это все еще актуально.
Брэд Паркс
2

В моем случае статус стал 0, когда я забыл поставить WWW перед своим доменом. Поскольку все мои запросы ajax были жестко запрограммированы на http: /WWW.mydomain.com, а загруженная веб-страница будет просто http://mydomain.com, это стало проблемой безопасности, потому что это другой домен. В итоге я сделал перенаправление в моем файле .htaccess, чтобы всегда ставить www впереди.

fellowworldcitizen
источник
1

В моем случае это произошло из-за того, что вызов AJAX был заблокирован браузером из-за политики одного и того же происхождения . Это было наименее ожидаемым, потому что все мои HTML-файлы и скрипты обслуживались из127.0.0.1 . Как они могли считаться имеющими разное происхождение?

В любом случае, первопричина заключалась в невинно выглядящей <base>метке:

<base href='<%=request.getScheme()%>://<%=request.getServerName() + ":" + request.getServerPort() + request.getContextPath()%>/'/>

Я удалил <base>тег, который мне кстати не понадобился, и теперь он работает нормально!

Saintali
источник
1

Я нашел новую и недокументированную причину для status == 0. Вот что у меня было:

XMLHttpRequest.status === 0
XMLHttpRequest.readyState === 0
XMLHttpRequest.responseText === ''
XMLHttpRequest.state() === 'rejected'

Это не было перекрестным источником, сетью или из-за отмененных запросов (по коду или с помощью пользовательской навигации). Ничего в консоли разработчика или в сетевом журнале.

Я смог найти очень мало документации по state () (Mozilla не перечисляет ее, W3C делает), и ни в одной из них не упоминалось «отклонено».

Оказывается, это был мой блокировщик рекламы (uBlock Origin в Firefox).

Джонатан Аменд
источник
1

В дополнение к ответу Ли вы можете найти дополнительную информацию о реальной причине, переключившись на синхронные запросы, так как вы также получите исключение:

function request(url) {
    var request = new XMLHttpRequest();
    try {
        request.open('GET', url, false);
        request.send(null);
    } catch (e) {
        console.log(url + ': ' + e);
    }
}

Например :

NetworkError: произошла сетевая ошибка.

МакИкс
источник
0

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

<form onsubmit="submitfunc(); return false;">

Ключом является return false, из-за которого форма не отправляется. Вы также можете просто вернуть false из submitfunc (), но я нахожу, что это явно написано для большей ясности.

samoz
источник
1
Предотвращение по умолчанию также работает для этого. Это функция javascript, которая предотвращает выполнение браузером поведения по умолчанию во время событий, позволяя вам аккуратно переопределить / предотвратить собственные функции ... return false тоже делает то же самое.
Кори Дэниелсон,
0

Следует отметить, что загрузка файла ajax, превышающая client_max_body_sizeдирективу для nginx, вернет этот код ошибки.

r3wt
источник
0

Если вы тестируете на локальном ПК, это не сработает. Чтобы протестировать пример Ajax, вам необходимо разместить файлы HTML на веб-сервере.

ExcelinEfendisi
источник
0

В моем случае ошибка произошла на странице, запрошенной с помощью протокола HTTP, с Javascript внутри нее, пытающимся выполнить запрос HTTPS. И наоборот.

После загрузки страницы нажмите F12 (или Ctrl + U) и посмотрите HTML-код своей страницы. Если вы видите что-то подобное в своем коде:

<!-- javascript request inside the page -->
<script>
var ajaxurl = "https://example.com/wp-admin/admin-ajax.php";
(...)
</script>

И ваша страница была запрошена таким образом:

http://example.com/example-page/2019/09/13/my-post/#elf_l1_Lw

Вы обязательно столкнетесь с этой ошибкой.

Чтобы исправить это, установите протокол запроса Javascript равным протоколу запроса страницы.

Эта ситуация, связанная с различными протоколами, для запросов страниц и js, упоминалась ранее в ответе Брэда Паркса, но, я думаю, представленная здесь методика диагностики проще для большинства пользователей.

aldemarcalazans
источник