¿Qué significa cuando una solicitud HTTP devuelve el código de estado 0?

130

¿Qué significa que las llamadas de red de JavaScript, como fetch o XMLHttpRequest, o cualquier otro tipo de solicitud de red HTTP, fallen con un código de estado HTTP de 0?

Esto no parece ser un código de estado HTTP válido, ya que otros códigos tienen tres dígitos en la especificación HTTP.

Intenté desconectar completamente la red como prueba. Puede no estar relacionado, pero eso dio como resultado el código de estado 17003 (IIRC), que la búsqueda superficial sugiere que significa "error en la búsqueda del servidor DNS".

El mismo código funciona bien desde algunas ubicaciones y sistemas, sin embargo, dentro de ciertos entornos falla con el código de estado 0 y no se proporciona texto de respuesta.

Esta es una POST HTTP típica a una URL de Internet. No involucra file: // que entiendo puede devolver 0 indicando éxito en Firefox.

Mike Nelson
fuente
¿Podría ser debido al firewall? ¿En qué sistema operativo está ejecutando la aplicación su cliente?
shahkalpesh
Puede ser útil: stackoverflow.com/a/12622082/386579
shasi kanth
Publicación relacionada - ¿Qué significa el código de estado HTTP 0?
RBT
He tenido el mismo problema en Firefox y descubrí que un bloqueador de anuncios Plugin evita todas las peticiones a las URL que contengan la palabrabanner
Ene

Respuestas:

56

Creo que el código de error indica que la respuesta estaba vacía (ya que ni siquiera se devolvieron los encabezados). Esto significa que la conexión se aceptó y luego se cerró correctamente (TCP FIN). Hay varias cosas que podrían causar esto, pero según su descripción, alguna forma de firewall parece ser el culpable más probable.

Mella
fuente
2
Creo que probablemente tengas razón. (Sin embargo, como se señaló en @sleepycod wininet.dll se esperaría que devuelva algún código de estado en ausencia de un código de estado http real )
Mike Mike
1
Esto no es necesariamente correcto. He tenido el mismo problema, pero en mi caso, nunca se envió una solicitud. La razón era que un bloqueador de anuncios Firefox impidió peticiones cuyos URL contienen la palabrabanner
Ene
194

Muchas de las respuestas aquí son incorrectas. Parece que las personas descubren qué estaba causando el estado == 0 en su caso particular y luego lo generalizan como la respuesta.

En términos prácticos, el estado == 0 para una XmlHttpRequest fallida debe considerarse un error indefinido.

La especificación W3C real define las condiciones para las cuales se devuelve cero aquí: https://fetch.spec.whatwg.org/#concept-network-error

Como puede ver en la especificación (fetch o XmlHttpRequest), este código podría ser el resultado de un error que ocurrió incluso antes de contactar al servidor.

Algunas de las situaciones comunes que producen este código de estado se reflejan en las otras respuestas, pero podría ser cualquiera o ninguno de estos problemas:

  1. Solicitud de origen cruzado ilegal (ver CORS )
  2. Bloqueo de firewall o filtrado
  3. La solicitud en sí fue cancelada en código
  4. Una extensión de navegador instalada está arruinando las cosas

Lo que sería útil sería que los navegadores proporcionaran informes detallados de errores para más de estos escenarios de estado == 0. De hecho, a veces status == 0 acompañará un mensaje útil de la consola, pero en otros no hay otra información.

Whitneyland
fuente
44
El complemento de Firefox NoScript puede cancelar la solicitud XHR a hosts no confiables.
Ivan Solntsev
55
+ 1, todo esto es correcto y "se produjo algún tipo de error" es la interpretación práctica. Para las personas interesadas en una lista completa de las posibles causas dadas por la especificación, publiqué un desglose en stackoverflow.com/a/26451773/1709587 .
Mark Amery
1
Entre los casos detallados por Mark Amery que me causan más problemas está el caso de Cors. Si el error provoca que la respuesta falle a la validación de CORS, por cierto, obtendrá un estado 0 en lugar del estado http, ya que cuando la validación de CORS falla, la respuesta no es accesible. Especialmente frustrante cuando se intenta detectar una API web que se encuentra en mantenimiento y responde 503. Si esta API no respeta los códigos durante el mantenimiento, no podrá detectar el 503, solo obtendrá 0, que puede ser causado por muchos otros cosas.
Frédéric
Problema de CORS que enfrenté: considere usar en httplugar de httpssi su página se cargó inicialmente httpy viceversa. Otras palabras no ejecutan ajax POSTvia httpssi se accedió a su página via httpy no realizan ajax POSTvia httpsi su página se accedió inicialmente a través de https.
Victor Ponamarev
Las solicitudes sincrónicas arrojan una excepción más significativa en el estado 0: stackoverflow.com/a/49573256/1192811
McX
35

Por lo que vale, dependiendo del navegador, las llamadas AJAX basadas en jQuery llamarán a su devolución de llamada exitosa con un código de estado HTTP de 0. Hemos encontrado que un código de estado de "0" generalmente significa que el usuario navegó a una página diferente antes La llamada AJAX completada.

No es la misma pila de tecnología que está utilizando, pero espero sea útil para alguien.

Cory R. King
fuente
Sí, la gente probablemente tenga ese problema mucho, ya que esta página ha tenido 10,000 visitas.
Mike Nelson
¿O debería decir 25,000 visitas?
Mike Nelson
3
Vale mucho: es exactamente lo que falló en mis pruebas automatizadas. ¡Muchas gracias!
alexfernandez
Votó no porque esta es "la" respuesta correcta, sino que es lo que estaba sucediendo en mi caso.
Juan Mendes
Esto definitivamente ocurre, pero no es la única razón por la que verá el código de error == 0. no puede suponer que solo el usuario se está alejando y, por lo tanto, filtra los mensajes de error de este tipo.
wal
14

wininet.dll devuelve los códigos de estado estándar y no estándar que se enumeran a continuación.

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 el código de estado "cero", ¿está tratando de hacer una solicitud en una página web local que se ejecuta en un servidor web o sin un servidor web?

XMLHttpRequest status = 0 y XMLHttpRequest statusText = unknown puede ayudarlo si no está ejecutando su script en un servidor web.

Christophe Eblé
fuente
Gracias por los códigos. No, no es una solicitud local, es una solicitud a un servidor web en Internet, desde un vbscript que se ejecuta localmente.
Mike Nelson
6

Solución alternativa: lo que terminamos haciendo

Pensamos que tenía que ver con problemas con el firewall, por lo que se nos ocurrió una solución que funcionó. Si alguien tiene este mismo problema, esto es lo que hicimos:

  1. Todavía escribimos los datos en un archivo de texto en el disco duro local como lo hicimos anteriormente, usando una HTA.

  2. Cuando el usuario hace clic en "enviar datos de vuelta al servidor", el HTA lee los datos y escribe una página HTML que incluye esos datos como una isla de datos XML (en realidad usando un IDIOMA SCRIPT = bloque de secuencia de comandos XML).

  3. La HTA lanza un enlace a la página HTML en el navegador.

  4. La página HTML ahora contiene el javascript que publica los datos en el servidor (usando Microsoft.XMLHTTP).

Espero que esto ayude a cualquiera con un requisito similar. En este caso, era un juego Flash utilizado en una computadora portátil en ferias comerciales. Nunca tuvimos acceso a la computadora portátil y solo pudimos enviarla por correo electrónico al cliente, ya que esta feria estaba ocurriendo en otro país.

Mike Nelson
fuente
Hola, estoy investigando un problema similar que le está ocurriendo a un cliente en producción. Dices que el problema fue causado por un firewall. ¿Recuerdas cuál fue el efecto causado por el firewall o qué estaba haciendo el firewall para causar esto?
Ibrahim Najjar
5

Un código de respuesta HTTP de 0 indica que la solicitud AJAX fue cancelada.

Esto puede ocurrir ya sea por un tiempo de espera, un aborto XHR o un firewall que pisa fuerte la solicitud. Un tiempo de espera es común, significa que la solicitud no se pudo ejecutar dentro de un tiempo especificado. Un aborto XHR es muy simple de hacer ... en realidad puede llamar a .abort () en un objeto XMLHttpRequest para cancelar la llamada AJAX. ( Esta es una buena práctica para una aplicación de una sola página si no desea que las llamadas AJAX regresen e intenten hacer referencia a objetos que han sido destruidos ) . Como se mencionó en la respuesta marcada, un firewall también podría cancelar la solicitud y activar esto 0 respuesta.

Abortar XHR: Abortar solicitudes 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 la pena señalar que ejecutar el método .abort () en un objeto XHR también activará la devolución de llamada de error. Si está haciendo algún tipo de manejo de errores que analiza estos objetos, notará rápidamente que un XHR abortado y un XHR de tiempo de espera son idénticos, pero con jQuery, el textStatus que se pasa a la devolución de llamada de error será "abortar" cuando se cancele y se produce un "tiempo de espera" con un tiempo de espera. Si está utilizando Zepto (muy similar a jQuery), el errorType será "error" cuando se cancela y "tiempo de espera" cuando se produce un tiempo de espera.

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

Como se detalla en esta respuesta en esta página , un código de estado de 0 significa que la solicitud falló por alguna razón, y una biblioteca de JavaScript interpretó el error como un código de estado de 0.

Para probar esto, puede hacer lo siguiente:

1) Use esta extensión de Chrome, Requestly para redirigir su url de la httpsversión de su url a la httpversión, ya que esto causará un error de seguridad de contenido mixto y, en última instancia, generará un código de estado de 0. La ventaja de este enfoque es que no no tiene que cambiar su aplicación en absoluto, y simplemente puede "reescribir" su URL usando esta extensión.

2) Cambie el código de su aplicación para hacer que su punto final redirija a la httpversión de su URL en lugar de la httpsversión (o viceversa). Si hace esto, la solicitud fallará con el código de estado 0.

Brad Parks
fuente
1
"Usar esta extensión de Chrome" - ¿Una extensión de Chrome? En una solicitud de HTA?
Quentin
44
Buen punto seguro! Pero la mayoría de las personas que llegan aquí no llegan para las aplicaciones de HTA. Están buscando en Google "javascript http status code 0" o algo así, y están llegando aquí, así que creo que la parte HTA de esta pregunta es de la menor importancia, en general, y en última instancia, esto sigue siendo relevante.
Brad Parks
2

En mi caso, el estado se convirtió en 0 cuando olvidaría poner la WWW delante de mi dominio. Como todas mis solicitudes de ajax estaban codificadas en http: /WWW.mydomain.com y la página web cargada sería http://mydomain.com, se convirtió en un problema de seguridad porque es un dominio diferente. Terminé haciendo una redirección en mi archivo .htaccess para poner siempre www al frente.

ciudadano del mundo
fuente
1

En mi caso, fue porque el navegador estaba bloqueando la llamada AJAX debido a la política del mismo origen . Era lo menos esperado, porque todos mis HTML y scripts de donde se servían 127.0.0.1. ¿Cómo podrían considerarse que tienen orígenes diferentes?

De todos modos, la causa raíz era una <base>etiqueta de aspecto inocente :

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

Eliminé la <base>etiqueta, que por cierto no necesitaba, ¡y ahora funciona bien!

Saintali
fuente
1

Encontré una razón nueva e indocumentada para el estado == 0. Esto es lo que tenía:

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

No era de origen cruzado, de red o debido a solicitudes canceladas (por código o por navegación del usuario). Nada en la consola del desarrollador o el registro de red.

Pude encontrar muy poca documentación sobre state () (Mozilla no lo enumera, W3C sí) y ninguno de ellos mencionó "rechazado".

Resulta que fue mi bloqueador de anuncios (uBlock Origin en Firefox).

Jonathan Enmienda
fuente
1

Además de la respuesta de Lee , puede encontrar más información sobre la causa real al cambiar a solicitudes sincrónicas , ya que también obtendrá una excepción:

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

Por ejemplo :

Error de red: se produjo un error de red.

McX
fuente
0

En caso de que alguien más se encuentre con este problema, esto me estaba dando problemas debido a la solicitud de AJAX y al envío de una solicitud de formulario normal. Lo resolví con la siguiente línea:

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

La clave allí es el retorno falso, lo que hace que el formulario no se envíe. También podría devolver falso desde el interior de submitfunc (), pero creo que escribirlo explícitamente es más claro.

Samoz
fuente
1
Prevenir por defecto también funciona para esto. Es una función de JavaScript que evita que el navegador ejecute un comportamiento predeterminado durante los eventos, lo que le permite anular / evitar claramente la funcionalidad nativa ... return false también hace lo mismo.
Cory Danielson
0

Cabe señalar que una carga de archivo ajax que exceda la client_max_body_sizedirectiva para nginx devolverá este código de error.

r3wt
fuente
0

Si está probando en una PC local, no funcionará. Para probar el ejemplo de Ajax, debe colocar los archivos HTML en un servidor web.

ExcelinEfendisi
fuente
0

En mi caso, el error ocurrió en una página solicitada con el protocolo HTTP, con un Javascript dentro tratando de hacer una solicitud HTTPS. Y viceversa.

Después de cargar la página, presione F12 (o Ctrl + U) y eche un vistazo al código HTML de su página. Si ve algo así en su código:

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

Y su página fue solicitada de esta manera:

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

Ciertamente enfrentará este error.

Para solucionarlo, configure el protocolo de la solicitud de Javascript igual al protocolo de solicitud de página.

Esta situación que involucra diferentes protocolos, para solicitudes de página y js, se mencionó anteriormente en la respuesta de Brad Parks pero, supongo que la técnica de diagnóstico presentada aquí es más fácil para la mayoría de los usuarios.

aldemarcalazans
fuente