O que significa quando uma solicitação HTTP retorna o código de status 0?

130

O que significa quando chamadas de rede JavaScript, como busca ou XMLHttpRequest, ou qualquer outro tipo de solicitação de rede HTTP, falham com um código de status HTTP 0?

Este não parece ser um código de status HTTP válido, pois outros códigos têm três dígitos na especificação HTTP.

Tentei desconectar completamente a rede como teste. Pode não estar relacionado, mas isso resultou no código de status 17003 (IIRC), que a pesquisa superficial sugere que significa "Falha na pesquisa do servidor DNS".

O mesmo código funciona bem em alguns locais e sistemas, no entanto, em certos ambientes, falha com o código de status 0 e não é fornecido o responseText.

Este é um HTTP POST típico para um URL da Internet. Ele não envolve file: //, que eu entendo pode retornar 0, indicando sucesso no Firefox.

Mike Nelson
fonte
Poderia ser devido a firewall? Em qual SO seu cliente está executando o aplicativo?
Shahkalpesh 17/05/09
Pode ser útil: stackoverflow.com/a/12622082/386579
shasi kanth
Eu tive o mesmo problema no Firefox e descobriu que um bloqueador de anúncios do plugin impede todas as solicitações para URLs que contenham a palavrabanner
Jan

Respostas:

56

Acredito que o código de erro indica que a resposta estava vazia (como nem mesmo os cabeçalhos foram retornados). Isso significa que a conexão foi aceita e depois fechada normalmente (TCP FIN). Há várias coisas que podem causar isso, mas, com base na sua descrição, alguma forma de firewall parece ser a culpada mais provável.

usuario
fonte
2
Eu acho que você está provavelmente certo. (Embora, como fora apontado por @sleepycod WinInet.dll seria esperado para retornar um código de status na ausência de um verdadeiro código de status http.)
mike nelson
1
Isto não é necessariamente correto. Eu tive o mesmo problema, mas no meu caso, uma solicitação nunca foi enviada. O motivo foi que um bloqueador de anúncios do Firefox impediu solicitações cujos URLs continham a palavrabanner
Jan
194

Muitas das respostas aqui estão erradas. Parece que as pessoas descobrem o que estava causando o status == 0 no seu caso particular e depois generalizam isso como a resposta.

Na prática, o status == 0 para um XmlHttpRequest com falha deve ser considerado um erro indefinido.

A especificação real do W3C define as condições para as quais o zero é retornado aqui: https://fetch.spec.whatwg.org/#concept-network-error

Como você pode ver na especificação (busca ou XmlHttpRequest), esse código pode ser o resultado de um erro que ocorreu mesmo antes do contato do servidor.

Algumas das situações comuns que produzem esse código de status são refletidas nas outras respostas, mas pode haver algum ou nenhum destes problemas:

  1. Solicitação de origem cruzada ilegal (consulte CORS )
  2. Bloqueio ou filtragem de firewall
  3. A solicitação em si foi cancelada no código
  4. Uma extensão de navegador instalada está atrapalhando as coisas

O que seria útil seria que os navegadores fornecessem relatórios detalhados de erros para mais desses cenários de status == 0. De fato, algumas vezes status == 0 acompanhará uma mensagem útil do console, mas em outras não há outras informações.

Whitneyland
fonte
4
O addon NoScript do Firefox pode cancelar a solicitação XHR para hosts não confiáveis.
precisa saber é o seguinte
5
+ 1, tudo isso é preciso e "ocorreu algum tipo de erro" é a interpretação prática. Para pessoas interessadas em uma lista abrangente de possíveis causas dadas pelas especificações, publiquei uma análise em stackoverflow.com/a/26451773/1709587 .
Mark-Amery #
1
Entre os casos detalhados por Mark Amery que mais me causam problemas está o caso cors. Se o erro levar a resposta a falhar na validação de cors, a propósito, você receberá um status 0 em vez do status http, pois quando a validação de cors falhar, a resposta não estará acessível. Especialmente frustrante ao tentar detectar uma API da Web em manutenção e responder 503. Se essa API não respeitar os cors enquanto estiver em manutenção, você não poderá detectar o 503, receberá apenas 0, o que pode ser causado por muitos outros coisas.
Frédéric
Problema do CORS que eu estava enfrentando: considere usar em httpvez de httpsse sua página foi carregada inicialmente httpe vice-versa. Outras palavras não executam ajax POSTvia httpsse sua página foi acessada via httpe não executam ajax POSTvia httpse sua página foi acessada inicialmente via https.
Victor Ponamarev
Solicitações síncronas lançam uma exceção mais significativa no status 0: stackoverflow.com/a/49573256/1192811
McX
35

Quanto vale a pena, dependendo do navegador, as chamadas AJAX baseadas em jQuery chamarão seu retorno de sucesso com um código de status HTTP igual a 0. Encontramos um código de status "0" geralmente significa que o usuário navegou para uma página diferente antes a chamada AJAX foi concluída.

Não é a mesma pilha de tecnologia que você está usando, mas espero que seja útil para alguém.

Cory R. King
fonte
Sim, as pessoas provavelmente entendem muito esse problema, pois esta página teve 10.000 visualizações.
Mike nelson #
Ou devo dizer 25.000 visualizações?
mike nelson
3
Vale muito: é exatamente o que falhou nos meus testes automatizados. Muito obrigado!
Alexfernandez
Votado não porque esta é "a" resposta certa, mas é o que estava acontecendo no meu caso.
Juan Mendes
Definitivamente, isso ocorre, mas não é o único motivo pelo qual você verá o código de erro == 0. você não pode presumir que é apenas o usuário navegando e, portanto, filtrar as mensagens de erro desse tipo.
2014
14

wininet.dll retorna códigos de status padrão e não padrão listados abaixo.

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

Para o código de status "zero", você está tentando fazer uma solicitação em uma página da Web local em execução em um servidor da Web ou sem um servidor da Web?

XMLHttpRequest status = 0 e XMLHttpRequest statusText = unknown podem ajudá-lo se você não estiver executando seu script em um servidor da web.

Christophe Eblé
fonte
Obrigado pelos códigos. Não, não é uma solicitação local, é uma solicitação para um servidor Web na Internet, de um vbscript em execução local.
26611 Mike Mike Nelson
6

Solução alternativa: o que acabamos fazendo

Nós achamos que isso tinha a ver com problemas de firewall e, por isso, criamos uma solução alternativa que fazia o truque. Se alguém tiver esse mesmo problema, eis o que fizemos:

  1. Ainda gravamos os dados em um arquivo de texto no disco rígido local, como fizemos anteriormente, usando um HTA.

  2. Quando o usuário clica em "enviar dados de volta ao servidor", o HTA lê os dados e grava uma página HTML que os inclui como uma ilha de dados XML (na verdade, usando um bloco de script SCRIPT LANGUAGE = XML).

  3. O HTA lança um link para a página HTML no navegador.

  4. A página HTML agora contém o javascript que lança os dados no servidor (usando Microsoft.XMLHTTP).

Espero que isso ajude qualquer pessoa com um requisito semelhante. Nesse caso, era um jogo em Flash usado em um laptop em feiras. Nunca tivemos acesso ao laptop e só podíamos enviá-lo por e-mail ao cliente, pois essa feira acontecia em outro país.

Mike Nelson
fonte
Olá, estou investigando um problema semelhante que está ocorrendo a um cliente em produção. Você diz que o problema foi causado por um firewall. Você se lembra de qual foi o efeito causado pelo firewall ou o que o firewall estava fazendo para causar isso?
Ibrahim Najjar
5

Um código de resposta HTTP 0 indica que a solicitação AJAX foi cancelada.

Isso pode acontecer a partir de um tempo limite, aborto por XHR ou um firewall bloqueando a solicitação. Um tempo limite é comum, significa que a solicitação falhou ao executar dentro de um tempo especificado. Um aborto XHR é muito simples de executar ... você pode realmente chamar .abort () em um objeto XMLHttpRequest para cancelar a chamada AJAX. ( Essa é uma boa prática para um aplicativo de página única, se você não quiser que as chamadas AJAX retornem e tentem fazer referência a objetos que foram destruídos. ) Como mencionado na resposta marcada, um firewall também seria capaz de cancelar a solicitação e acionar esta solicitação. 0 resposta.

Anulação de XHR: Anulação de solicitações de Ajax usando 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()

Vale ressaltar que a execução do método .abort () em um objeto XHR também acionará o retorno de chamada de erro. Se você estiver executando algum tipo de tratamento de erro que analise esses objetos, notará rapidamente que um XHR abortado e um XHR de tempo limite são idênticos, mas com jQuery o textStatus passado para o retorno de chamada de erro será "abortado" quando abortado. e "timeout" com um timeout ocorre. Se você estiver usando o Zepto (muito parecido com o jQuery), o errorType será "error" quando abortado e "timeout" quando ocorrer um timeout.

jQuery: error(jqXHR, textStatus, errorThrown);
Zepto:  error(xhr, errorType, error);
Cory Danielson
fonte
4

Conforme detalhado por esta resposta nesta página , um código de status 0 significa que a solicitação falhou por algum motivo e uma biblioteca javascript interpretou a falha como um código de status 0.

Para testar isso, você pode fazer o seguinte:

1) Use esta extensão do Chrome, Requestly para redirecionar sua URL da httpsversão para a httpversão, pois isso causará um erro de segurança de conteúdo misto e, finalmente, gerará um código de status igual a 0. A vantagem dessa abordagem é que você não é necessário alterar seu aplicativo e você pode simplesmente "reescrever" seu URL usando esta extensão.

2) Altere o código do seu aplicativo para opcionalmente redirecionar o terminal para a httpversão do seu URL em vez da httpsversão (ou vice-versa). Se você fizer isso, a solicitação falhará com o código de status 0.

Brad Parks
fonte
1
"Usar esta extensão do Chrome" - Uma extensão do Chrome? Em um aplicativo HTA?
Quentin
4
Bom ponto, com certeza! Mas a maioria das pessoas que chegam aqui não está chegando aqui para aplicativos HTA. Eles estão pesquisando "código de status http javascript 0" ou algo assim, e chegando aqui - então acho que a parte HTA dessa pergunta é da menor importância, em geral, e, no final das contas, isso ainda é relevante.
Brad Parks
2

No meu caso, o status se tornou 0 quando eu esqueci de colocar a WWW na frente do meu domínio. Como todas as minhas solicitações de ajax foram codificadas em http: /WWW.mydomain.com e a página carregada seria apenas http://mydomain.com , tornou-se um problema de segurança porque é um domínio diferente. Acabei fazendo um redirecionamento no meu arquivo .htaccess para sempre colocar www na frente.

companheiro
fonte
1

No meu caso, foi porque a chamada AJAX estava sendo bloqueada pelo navegador devido à política de mesma origem . Era a coisa menos esperada, porque todos os meus HTMLs e scripts eram servidos 127.0.0.1. Como eles podem ser considerados como tendo origens diferentes?

De qualquer forma, a causa raiz era uma <base>tag de aparência inocente :

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

Eu removi a <base>tag, da qual não precisava, e agora funciona bem!

Saintali
fonte
1

Encontrei um motivo novo e não documentado para o status == 0. Aqui está o que eu tinha:

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

Não era de origem cruzada, de rede ou devido a solicitações canceladas (por código ou pela navegação do usuário). Nada no console do desenvolvedor ou no log da rede.

Eu pude encontrar muito pouca documentação sobre state () (a Mozilla não a lista, o W3C) e nenhuma delas mencionou "rejeitada".

Acontece que era meu bloqueador de anúncios (uBlock Origin no Firefox).

Jonathan Amend
fonte
1

Além da resposta de Lee , você pode encontrar mais informações sobre a causa real, alternando para solicitações síncronas , pois também terá uma exceção:

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

Por exemplo :

Erro de rede: ocorreu um erro de rede.

McX
fonte
0

No caso de alguém encontrar esse problema, isso estava me causando problemas devido à solicitação AJAX e a uma solicitação de formulário normal sendo enviada. Eu o resolvi com a seguinte linha:

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

A chave lá é o retorno false, que faz com que o formulário não seja enviado. Você também pode retornar false de dentro de submitfunc (), mas acho explicitamente escrevê-lo para ser mais claro.

samoz
fonte
1
Impedir que o padrão funcione para isso também. É uma função javascript que impede que o navegador execute o comportamento padrão durante os eventos, permitindo que você substitua / impeça a funcionalidade nativa ... devolver false também faz a mesma coisa.
Cory Danielson
0

Note-se que um upload de arquivo ajax que excede a client_max_body_sizediretiva para nginx retornará esse código de erro.

r3wt
fonte
0

Se você estiver testando no PC local, ele não funcionará. Para testar o exemplo do Ajax, você precisa colocar os arquivos HTML em um servidor web.

ExcelinEfendisi
fonte
0

No meu caso, o erro ocorreu em uma página solicitada com protocolo HTTP, com um Javascript dentro dele tentando fazer uma solicitação HTTPS. E vice versa.

Após o carregamento da página, pressione F12 (ou Ctrl + U) e veja o código HTML da sua página. Se você vir algo assim no seu código:

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

E sua página foi solicitada desta maneira:

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

Você certamente enfrentará esse erro.

Para corrigi-lo, defina o protocolo da solicitação Javascript igual ao protocolo da solicitação da página.

Essa situação envolvendo protocolos diferentes, para solicitações de páginas e js, foi mencionada anteriormente na resposta de Brad Parks , mas acho que a técnica de diagnóstico apresentada aqui é mais fácil para a maioria dos usuários.

aldemarcalazans
fonte