¿Tiene algún significado un código de estado HTTP de 0?

91

Parece que cuando realiza una XMLHttpRequest desde un script en un navegador, si el navegador está configurado para funcionar sin conexión o si se desconecta el cable de red, la solicitud se completa con un error y con un estado = 0. 0 no se incluye entre los permitidos Códigos de estado HTTP.

¿Qué significa un código de estado de 0? ¿Significa lo mismo en todos los navegadores y para todas las utilidades de cliente HTTP? ¿Es parte de la especificación HTTP o es parte de alguna otra especificación de protocolo? Parece significar que la solicitud HTTP no se pudo realizar en absoluto, quizás porque la dirección del servidor no se pudo resolver.

¿Qué mensaje de error es apropiado mostrarle al usuario? "¿No está conectado a Internet, o el sitio web tiene problemas o puede haber un error de escritura en la dirección"?

Debo agregar a esto que veo el comportamiento en FireFox cuando se establece en "Trabajar sin conexión", pero no en Microsoft Internet Explorer cuando se establece en "Trabajar sin conexión". En IE, el usuario obtiene un cuadro de diálogo que ofrece la opción de conectarse. FireFox no notifica al usuario antes de devolver el error.

Estoy preguntando esto en respuesta a una solicitud para "mostrar un mensaje de error mejor". Lo que hace Internet Explorer es bueno. Le dice al usuario qué está causando el problema y le da la opción de solucionarlo. Para dar una UX equivalente con FireFox, necesito inferir la causa del problema e informar al usuario. Entonces, ¿qué puedo inferir en total del estado 0? ¿Tiene un significado universal o no me dice nada?

Mark Lutton
fuente
Consulte esta pregunta, que cubre el mismo tema: stackoverflow.com/questions/872206/…
Scott Stafford
3
Creo que esta es la respuesta más precisa: stackoverflow.com/a/14507670/700206
whitneyland
Otra publicación relacionada - ¿Qué significa el código de estado HTTP 0?
RBT

Respuestas:

153

Respuesta corta

No es un código de respuesta HTTP, pero WhatWG lo documenta como un valor válido para el atributo de estado de una XMLHttpRequesto una respuesta Fetch.

En términos generales, es un valor predeterminado que se utiliza cuando no hay un código de estado HTTP real para informar y / o se produjo un error al enviar la solicitud o al recibir la respuesta. Los posibles escenarios donde este es el caso incluyen, pero no se limitan a:

  • La solicitud aún no se ha enviado o se canceló.
  • El navegador todavía está esperando recibir el estado de respuesta y los encabezados.
  • La conexión se cortó durante la solicitud.
  • La petición caducó.
  • La solicitud encontró un bucle de redireccionamiento infinito.
  • El navegador conoce el estado de la respuesta, pero no se le permite acceder a él debido a restricciones de seguridad relacionadas con la Política del mismo origen .

Respuesta larga

Primero, para reiterar: 0 no es un código de estado HTTP. Hay una lista completa de ellos en RFC 7231 Sección 6.1 , que no incluye 0, y la introducción a la sección 6 establece claramente que

El elemento de código de estado es un código entero de tres dígitos.

que 0 no lo es.

Sin embargo, 0 como valor del .statusatributo de un objeto XMLHttpRequest está documentado, aunque es un poco complicado rastrear todos los detalles relevantes. Comenzamos en https://xhr.spec.whatwg.org/#the-status-attribute , documentando el .statusatributo, que simplemente dice:

El statusatributo debe devolver la respuesta ‘s de estado .

Eso puede sonar vacío y tautológico, ¡pero en realidad hay información aquí! Recuerde que esta documentación habla aquí sobre el .responseatributo de XMLHttpRequestuna respuesta, no una respuesta, por lo que nos dice que la definición del estado en un objeto XHR se difiere a la definición del estado de una respuesta en la especificación Fetch.

Pero, ¿qué objeto de respuesta? ¿Qué pasa si todavía no hemos recibido una respuesta? El enlace en línea de la palabra "respuesta" nos lleva a https://xhr.spec.whatwg.org/#response , que explica:

An XMLHttpRequesttiene una respuesta asociada. A menos que se indique lo contrario, se trata de un error de red .

Entonces, la respuesta cuyo estado estamos obteniendo es por defecto un error de red. Y al buscar en todos los lugares donde se usa la frase "establecer respuesta a" en la especificación XHR, podemos ver que se establece en cinco lugares:

Mirando el estándar Fetch , podemos ver que:

Un error de red es una respuesta cuyo estado es siempre0

por lo que podemos decir inmediatamente que veremos un estado de 0 en un objeto XHR en cualquiera de los casos en los que la especificación XHR dice que la respuesta debe configurarse como un error de red. (Curiosamente, esto incluye el caso en el que el flujo del cuerpo tiene "errores", lo que la especificación Fetch nos dice que puede suceder durante el análisis del cuerpo después de haber recibido el estado, por lo que, en teoría, supongo que es posible que un objeto XHR tenga su estado establecido en 200, luego encuentra un error de memoria insuficiente o algo así mientras recibe el cuerpo y, por lo tanto, cambia su estado a 0).

También notamos en el estándar Fetch que existen un par de otros tipos de respuesta cuyo estado se define en 0, cuya existencia se relaciona con solicitudes de origen cruzado y la política del mismo origen:

Una respuesta filtrada opaca es una respuesta filtrada cuyo ... estado es 0...

Una respuesta filtrada de redireccionamiento opaco es una respuesta filtrada cuyo ... estado es 0...

(Se omiten varios otros detalles sobre estos dos tipos de respuesta).

Pero más allá de estos, también hay muchos casos en los que el algoritmo Fetch (en lugar de la especificación XHR, que ya hemos visto) pide que el navegador devuelva un error de red. De hecho, la frase "devolver un error de red" aparece 40 veces en el estándar Fetch. No intentaré enumerar los 40 aquí, pero observo que incluyen:

  • El caso en el que el esquema de la solicitud no se reconoce (por ejemplo, al intentar enviar una solicitud a madeupscheme: //foobar.com)
  • La instrucción maravillosamente vaga "En caso de duda, devuelva un error de red". en los algoritmos para manejar ftp: // y file: // URL
  • Redirecciones infinitas: "Si el número de redirecciones de la solicitud es veinte, devuelve un error de red".
  • Un montón de problemas relacionados con CORS, como "Si la contaminación de respuesta de httpRequest no es" cors "y la verificación de la política de recursos de origen cruzado con devoluciones de solicitud y respuesta bloqueadas, devuelve un error de red".
  • Fallos de conexión: "Si la conexión falla, devuelve un error de red".

En otras palabras: cada vez que algo sale mal, además de obtener un código de estado de error HTTP real como 500 o 400 del servidor, termina con un atributo de estado de 0 en su objeto XHR o Fetch response object en el navegador. El número de posibles causas específicas enumeradas en la especificación es enorme.

Finalmente: si está interesado en el historial de la especificación por alguna razón, tenga en cuenta que esta respuesta se reescribió por completo en 2020, y que puede estar interesado en la revisión anterior de esta respuesta , que analizó esencialmente las mismas conclusiones de la especificaciones W3 más antiguas (y mucho más simples) para XHR, antes de que fueran reemplazadas por las especificaciones WhatWG más modernas y más complicadas a las que se refieren estas respuestas.

Mark Amery
fuente
53

El estado 0 aparece cuando se canceló una llamada ajax antes de obtener la respuesta actualizando la página o solicitando una URL inaccesible.

este estado no está documentado pero existe sobre ajax y llamadas makeRequest desde gadget.io.

mnk
fuente
4
Hola, ¿Hay alguna forma de diferenciar entre una solicitud fallida ("Sin red") y una solicitud cancelada?
Ankur
2
Este estado se documenta como un estado XmlHttpRequest. Por supuesto, no es un estado http, pero está documentado. w3.org/TR/XMLHttpRequest/#the-status-attribute Consulte la respuesta de Mark Amery para obtener más detalles.
Frédéric
4

Sepa que es una publicación antigua. Pero estos problemas aún existen.

Estos son algunos de mis hallazgos sobre el tema, explicados a grandes rasgos.

"Estado" 0 significa una de tres cosas, según la especificación XMLHttpRequest:

  • La resolución del nombre dns falló (eso es, por ejemplo, cuando se desconecta el enchufe de red)

  • el servidor no respondió (también conocido como inaccesible o sin respuesta)

  • la solicitud fue cancelada debido a un problema de CORS (el aborto lo realiza el usuario-agente y sigue a OPTIONS fallidas antes del vuelo).

Si desea ir más allá, profundice en los aspectos internos de XMLHttpRequest. Sugiero leer la secuencia de actualización del estado listo ([0,1,2,3,4] es la secuencia normal, [0,1,4] corresponde al estado 0, [0,1,2,4] significa que no hay contenido enviado que puede ser un error o no). Es posible que también desee adjuntar oyentes al xhr (onreadystatechange, onabort, onerror, ontimeout) para averiguar los detalles.

De la especificación (especificación 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
fuente
1
Todas las causas posibles en su lista aquí son correctas, pero su lista no es exhaustiva. Por ejemplo, le faltan tiempos de espera, ciclos de redireccionamiento infinitos y otras causas detalladas en mi respuesta . Sin embargo, el puntero a la nueva especificación XHR viva es útil; Debo actualizar mi respuesta para citar eso en lugar de la antigua especificación W3.
Mark Amery
0

Desde iOS 9, debe agregar "Configuración de seguridad de transporte de aplicaciones" a su archivo info.plist y permitir "Permitir cargas arbitrarias" antes de realizar una solicitud al servicio web HTTP no seguro. Tuve este problema en una de mis aplicaciones.

Nirav
fuente
-1

Sí, de alguna manera se abortó la llamada ajax. La causa puede ser la siguiente.

  1. Antes de completar la solicitud ajax, el usuario navegó a otra página.
  2. La solicitud de Ajax tiene tiempo de espera.
  3. El servidor no puede devolver ninguna respuesta.
Vinayak
fuente