Um código de status HTTP de 0 tem algum significado?

91

Parece que quando você faz um XMLHttpRequest de um script em um navegador, se o navegador estiver configurado para funcionar off-line ou se o cabo de rede for desconectado, a solicitação será concluída com um erro e com status = 0. 0 não está listado entre os permitidos Códigos de status HTTP.

O que significa um código de status de 0? Isso significa a mesma coisa em todos os navegadores e para todos os utilitários de cliente HTTP? É parte da especificação HTTP ou de alguma outra especificação de protocolo? Parece significar que a solicitação HTTP não pôde ser feita, talvez porque o endereço do servidor não pudesse ser resolvido.

Qual mensagem de erro é apropriada para mostrar ao usuário? "Ou você não está conectado à internet ou o site está com problemas ou pode haver um erro de digitação no endereço"?

Devo acrescentar que vejo o comportamento no FireFox quando definido como "Trabalhar Offline", mas não no Microsoft Internet Explorer quando definido como "Trabalhar Offline". No IE, o usuário obtém uma caixa de diálogo com a opção de ficar online. O FireFox não notifica o usuário antes de retornar o erro.

Estou pedindo isso em resposta a uma solicitação para "mostrar uma mensagem de erro melhor". O que o Internet Explorer faz é bom. Ele informa ao usuário o que está causando o problema e oferece a opção de corrigi-lo. Para fornecer uma UX equivalente com FireFox, preciso inferir a causa do problema e informar ao usuário. Então, o que no total posso inferir do Status 0? Tem um significado universal ou não me diz nada?

Mark Lutton
fonte
Consulte esta pergunta, que cobre o mesmo tópico: stackoverflow.com/questions/872206/…
Scott Stafford
3
Acredito que esta seja a resposta mais precisa: stackoverflow.com/a/14507670/700206
whitneyland
Outra postagem relacionada - O que significa o código de status HTTP 0
RBT

Respostas:

153

Resposta curta

Não é um código de resposta HTTP, mas é documentado por WhatWG como um valor válido para o atributo de status de uma XMLHttpRequestou uma resposta Fetch.

Em termos gerais, é um valor padrão usado quando não há nenhum código de status HTTP real para relatar e / ou ocorreu um erro no envio da solicitação ou no recebimento da resposta. Os cenários possíveis em que este é o caso incluem, mas não estão limitados a:

  • A solicitação ainda não foi enviada ou foi cancelada.
  • O navegador ainda está esperando para receber o status de resposta e os cabeçalhos.
  • A conexão caiu durante a solicitação.
  • O pedido excedeu o tempo limite.
  • A solicitação encontrou um loop de redirecionamento infinito.
  • O navegador conhece o status da resposta, mas você não tem permissão para acessá-lo devido a restrições de segurança relacionadas à Política de mesma origem .

Resposta longa

Em primeiro lugar, para reiterar: 0 não é um código de status HTTP. Há uma lista completa deles na RFC 7231 Seção 6.1 , que não inclui 0, e a introdução da seção 6 afirma claramente que

O elemento status-code é um código inteiro de três dígitos

qual 0 não é.

No entanto, 0 como um valor do .statusatributo de um objeto XMLHttpRequest é documentado, embora seja um pouco complicado rastrear todos os detalhes relevantes. Começamos em https://xhr.spec.whatwg.org/#the-status-attribute , documentando o .statusatributo, que simplesmente afirma:

O statusatributo deve retornar a resposta do estado .

Isso pode parecer vazio e tautológico, mas na realidade há informações aqui! Lembre-se de que esta documentação está falando aqui sobre o .responseatributo de uma XMLHttpRequest, não de uma resposta, então isso nos diz que a definição do status em um objeto XHR é adiada para a definição do status de uma resposta na especificação Fetch.

Mas que objeto de resposta? E se ainda não tivermos recebido uma resposta? O link embutido na palavra "resposta" nos leva a https://xhr.spec.whatwg.org/#response , que explica:

Um XMLHttpRequesttem uma resposta associada. Salvo indicação em contrário, é um erro de rede .

Portanto, a resposta cujo status estamos obtendo é, por padrão, um erro de rede. E pesquisando em todos os lugares em que a frase "definir resposta para" é usada na especificação XHR, podemos ver que ela está definida em cinco lugares:

Olhando no padrão Fetch , podemos ver que:

Um erro de rede é uma resposta cujo status é sempre0

portanto, podemos dizer imediatamente que veremos o status 0 em um objeto XHR em qualquer um dos casos em que a especificação XHR diz que a resposta deve ser definida como um erro de rede. (Curiosamente, isso inclui o caso em que o fluxo do corpo fica "com erro", o que a especificação Fetch nos diz que pode acontecer durante a análise do corpo após ter recebido o status - então, em teoria, suponho que seja possível para um objeto XHR ter seu status definido como 200, em seguida, encontra um erro de falta de memória ou algo assim ao receber o corpo e, portanto, altere seu status de volta para 0.)

Também observamos no padrão Fetch que existem alguns outros tipos de resposta cujo status é definido como 0, cuja existência está relacionada a solicitações de origem cruzada e à política de mesma origem:

Uma resposta filtrada opaca é uma resposta filtrada cujo ... status é 0...

Uma resposta filtrada de redirecionamento opaco é uma resposta filtrada cujo ... status é 0...

(vários outros detalhes sobre esses dois tipos de resposta omitidos).

Mas, além disso, também existem muitos casos em que o algoritmo Fetch (em vez da especificação XHR, que já examinamos) exige que o navegador retorne um erro de rede! Na verdade, a frase "retornar um erro de rede" aparece 40 vezes no padrão Fetch. Não tentarei listar todos os 40 aqui, mas observo que eles incluem:

  • O caso em que o esquema da solicitação não é reconhecido (por exemplo, tentando enviar uma solicitação para madeupscheme: //foobar.com)
  • A instrução maravilhosamente vaga "Em caso de dúvida, retorne um erro de rede." nos algoritmos para lidar com URLs ftp: // e file: //
  • Redirecionamentos infinitos: "Se a contagem de redirecionamentos da solicitação for vinte, retorna um erro de rede."
  • Um monte de problemas relacionados ao CORS, como "Se a contaminação da resposta do httpRequest não for" cors "e a verificação da política de recursos de origem cruzada com os retornos de solicitação e resposta bloqueados, retorne um erro de rede."
  • Falhas de conexão: "Se a conexão falhar, retorne um erro de rede."

Em outras palavras: sempre que algo dá errado além de obter um código de status de erro HTTP real, como 500 ou 400 do servidor, você acaba com um atributo de status de 0 em seu objeto XHR ou objeto Fetch response no navegador. O número de possíveis causas específicas enumeradas nas especificações é vasto.

Finalmente: se você estiver interessado na história da especificação por algum motivo, observe que esta resposta foi completamente reescrita em 2020, e que você pode estar interessado na revisão anterior desta resposta , que analisou essencialmente as mesmas conclusões do especificações W3 mais antigas (e muito mais simples) para XHR, antes de serem substituídas pelas especificações mais modernas e complicadas de WhatWG a que essas respostas se referem.

Mark Amery
fonte
53

status 0 aparece quando uma chamada ajax foi cancelada antes de obter a resposta, atualizando a página ou solicitando um URL que está inacessível.

este status não é documentado, mas existe nas chamadas ajax e makeRequest de gadget.io.

mnk
fonte
4
Olá, Existe alguma maneira de diferenciar entre falha ("Sem rede") e solicitação cancelada?
Ankur
2
Este status é documentado como sendo um status XmlHttpRequest. Claro que não é um status http, mas está documentado. w3.org/TR/XMLHttpRequest/#the-status-attribute Consulte a resposta de Mark Amery para obter mais detalhes.
Frédéric
4

Saiba que é um post antigo. Mas esses problemas ainda existem.

Aqui estão algumas das minhas descobertas sobre o assunto, explicadas de forma grosseira.

"Status" 0 significa uma de 3 coisas, de acordo com a especificação XMLHttpRequest:

  • Falha na resolução do nome DNS (por exemplo, quando o plugue da rede é retirado)

  • servidor não respondeu (também conhecido como inacessível ou sem resposta)

  • a solicitação foi abortada devido a um problema de CORS (o aborto é realizado pelo agente do usuário e segue um pré-voo OPTIONS com falha).

Se você quiser ir mais longe, mergulhe fundo nos interiores de XMLHttpRequest. Eu sugiro ler a seqüência de atualização de estado pronto ([0,1,2,3,4] é a seqüência normal, [0,1,4] corresponde ao status 0, [0,1,2,4] significa sem conteúdo enviado, o que pode ser um erro ou não). Você também pode querer anexar ouvintes ao xhr (onreadystatechange, onabort, onerror, ontimeout) para descobrir os detalhes.

Das especificações (especificação 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;
Obotor
fonte
1
Todas as causas possíveis em sua lista estão corretas, mas sua lista não é completa. Por exemplo, você está perdendo tempos limite, loops de redirecionamento infinitos e outras causas detalhadas em minha resposta . No entanto, o ponteiro para a nova especificação XHR viva é útil; Devo atualizar minha resposta para citar isso, em vez da antiga especificação W3.
Mark Amery
0

Desde o iOS 9, você precisa adicionar "Configurações de segurança de transporte de aplicativos" ao seu arquivo info.plist e permitir "Permitir cargas arbitrárias" antes de fazer uma solicitação para um serviço da web HTTP não seguro. Tive esse problema em um dos meus aplicativos.

Nirav
fonte
-1

Sim, de alguma forma a chamada ajax foi abortada. A causa pode ser a seguinte.

  1. Antes da conclusão da solicitação ajax, o usuário navegou para outra página.
  2. A solicitação Ajax tem tempo limite.
  3. O servidor não pode retornar nenhuma resposta.
Vinayak
fonte