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

Parece que cuando hace un XMLHttpRequest desde una secuencia de comandos en un navegador, si el navegador está configurado para trabajar fuera de línea o si se extrae el cable de red, la solicitud se completa con un error y con el estado = 0. 0 no figura entre permisible 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 los clientes 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, tal vez porque la dirección del servidor no se pudo resolver.

¿Qué mensaje de error es apropiado para mostrar al usuario? “O no está conectado a Internet, o el sitio web tiene problemas o puede haber un error de tipeo en la dirección”?

Debo añadir 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 le da la opción de conectarse. FireFox no notifica al usuario antes de devolver el error.

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

Respuesta corta

No es un código de respuesta HTTP, pero está documentado por W3 como un valor válido para el atributo de status de un XMLHttpRequest (y por lo tanto también de un objeto jqXHR , para usuarios de jQuery).

Abarca toda una gama de situaciones posibles en las que no hay un código de respuesta HTTP real disponible para informar, ya sea porque no ha enviado la solicitud, la abortó explícitamente, la página se está descargando o x falló para uno de los muchos valores posibles de x .

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 de entero de tres dígitos

que 0 no es

Sin embargo, 0 como un valor del atributo de status de un objeto XMLHttpRequest está documentado. De la documentación en http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute :

4.7.1 El atributo de estado

El atributo de status debe devolver el resultado de ejecutar estos pasos:

  1. Si el estado es INESTABLE o ABIERTO, devuelva 0.

  2. Si el indicador de error está establecido, devuelve 0.

  3. Devuelve el código de estado HTTP.

Podemos profundizar en la especificación y averiguar qué significan esas condiciones para devolver 0. De http://www.w3.org/TR/XMLHttpRequest/#states :

4.5 Estados

UNSENT (valor numérico 0)

El objeto ha sido construido.

OPENED (valor numérico 1)

El método open() ha sido invocado con éxito. Durante este estado, los encabezados de las solicitudes se pueden establecer usando setRequestHeader() y la solicitud se puede realizar utilizando el método send() .

El indicador de error indica algún tipo de error de red o terminación de búsqueda. Inicialmente está desarmado.

También es relevante tener en cuenta que el siguiente estado posible después de UNSENT y HEADERS_RECEIVED es HEADERS_RECEIVED :

HEADERS_RECEIVED (valor numérico 2)

Se han seguido todos los redireccionamientos (si corresponde) y se han recibido todos los encabezados HTTP de la respuesta final. Varios miembros de respuesta del objeto están ahora disponibles.

Al juntar todo esto, la respuesta corta es que 0 es simplemente lo que devuelve el atributo de status de un objeto XMLHttpRequest cuando no hay un código de estado real que devolver, ya sea porque:

  • La solicitud aún no se ha enviado, o
  • La solicitud ha sido enviada pero los encabezados de la respuesta aún no se han recibido, o
  • Se ha producido una de las muchas circunstancias posibles, enumeradas en los documentos , que han provocado que se establezca el “indicador de error”.

De acuerdo, pero ¿qué errores pueden hacer que se establezca este misterioso “indicador de error”? Si pulsa CTRL-F para ‘indicador de error’ en la documentación de W3, encontrará que no se configura al enviar la solicitud, y solo se establece como parte del algoritmo para “finalizar la solicitud”. Buscando todos los lugares en los que se invoca el algoritmo, descubrirá que sucede cuando:

  • La solicitud se abre (o vuelve a abrir) con el método open()
  • La solicitud es basura recolectada (por ejemplo, al salir de la página)
  • La solicitud se cancela con el método abort()
  • Se produce un “error de solicitud”, que puede suceder cuando se produce una de las siguientes situaciones:

    • Se produce un error de red, que puede suceder si

      • Hay un bucle infinito de redirección
      • Hay

        Errores de DNS, falla de negociación de TLS u otro tipo de error de red

      • La solicitud fue una solicitud CORS y la respuesta no se puede compartir
    • Se produce un error de cancelación, que solo puede suceder si

      El usuario final cancela la solicitud

      Lo que sea que eso signifique. No conozco ningún navegador que muestre a los usuarios cuándo se producen las solicitudes AJAX y les da la oportunidad de cancelarlas explícitamente, por lo que creo que esta es, al menos hoy, irrelevante.

    • Se produce un error de tiempo de espera, lo que significa, razonablemente, que

      timeout no es 0 y desde que se inició la solicitud, la cantidad de milisegundos especificada por el timeout de timeout ha pasado

En lo que respecta a XMLHttpRequest , eso es todo.

Más allá de XMLHttpRequest , especularía que las bibliotecas HTTP en idiomas fuera de JavaScript pueden estar usando un código de estado 0 de manera similar, como un valor predeterminado cuando no se ha recibido ningún código de estado del servidor.

el estado 0 aparece cuando se canceló una llamada ajax antes de obtener la respuesta refrescando la página o solicitando una URL que no se puede alcanzar.

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

de la documentación http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute significa que una solicitud fue cancelada antes de ir a ningún lado

Sabes que es una publicación anterior. Pero estos problemas aún existen.

Aquí hay algunos de mis hallazgos sobre el tema, explicados groseramente.

“Estado” 0 significa una de 3 cosas, según la especificación XMLHttpRequest:

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

  • el servidor no respondió (también conocido como inalcanzable o no correspondido)

  • se anuló la solicitud debido a un problema CORS (el usuario-agente realiza el aborto y sigue un OP-Flight fallido).

Si quieres ir más lejos, profundiza en los inicios de XMLHttpRequest. Sugiero leer la secuencia de actualización de 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). También puede adjuntar oyentes al xhr (onreadystatechange, onabort, onerror, ontimeout) para descubrir 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; 

Desde iOS 9, debe agregar “Configuración de seguridad de transporte de la aplicación” 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.

Sí, de alguna forma la llamada ajax abortó. La causa puede estar siguiendo.

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