Qu'est-ce que cela signifie lorsqu'une requête HTTP renvoie le code d'état 0?

130

Qu'est-ce que cela signifie lorsque les appels réseau JavaScript tels que fetch ou XMLHttpRequest, ou tout autre type de requête réseau HTTP, échouent avec un code d'état HTTP de 0?

Cela ne semble pas être un code d'état HTTP valide car les autres codes sont à trois chiffres dans la spécification HTTP.

J'ai essayé de débrancher complètement le réseau à titre de test. Cela n'a peut-être pas de rapport, mais cela a abouti au code d'état 17003 (IIRC), qui, selon une recherche superficielle, signifie «échec de la recherche du serveur DNS».

Le même code fonctionne correctement à partir de certains emplacements et systèmes, mais dans certains environnements, il échoue avec le code d'état 0 et aucun responseText n'est fourni.

Il s'agit d'un HTTP POST typique vers une URL Internet. Cela n'implique pas file: // qui, je crois, peut renvoyer 0 indiquant le succès dans Firefox.

Mike Nelson
la source
Cela pourrait-il être dû au pare-feu? Sur quel système d'exploitation votre client exécute-t-il l'application?
shahkalpesh
Peut-être utile: stackoverflow.com/a/12622082/386579
shasi kanth
Article connexe - Que signifie le code d'état HTTP 0
RBT
J'ai eu le même problème dans Firefox et j'ai découvert qu'un plugin de blocage de publicités empêche toutes les requêtes aux URL contenant le motbanner
janvier

Réponses:

56

Je crois que le code d'erreur indique que la réponse était vide (car même les en-têtes n'ont pas été retournés). Cela signifie que la connexion a été acceptée puis fermée correctement (TCP FIN). Il y a un certain nombre de choses qui pourraient causer cela, mais d'après votre description, une forme de pare-feu semble être le coupable le plus probable.

pseudo
la source
2
Je pense que vous avez probablement raison. (Bien que, comme indiqué par @sleepycod wininet.dll, on s'attend à ce qu'il renvoie un code d'état en l'absence d'un véritable code d'état http.)
Mike Nelson
1
Ce n'est pas forcément correct. J'ai eu le même problème, mais dans mon cas, une demande n'a jamais été envoyée. La raison en était qu'un bloqueur de publicités Firefox empêchait les requêtes dont les URL contiennent le motbanner
janvier
194

Beaucoup de réponses ici sont fausses. Il semble que les gens comprennent ce qui causait le statut == 0 dans leur cas particulier, puis généralisent cela comme réponse.

En pratique, status == 0 pour une XmlHttpRequest ayant échoué doit être considéré comme une erreur non définie.

La spécification réelle du W3C définit les conditions pour lesquelles zéro est renvoyé ici: https://fetch.spec.whatwg.org/#concept-network-error

Comme vous pouvez le voir dans la spécification (fetch ou XmlHttpRequest), ce code pourrait être le résultat d'une erreur survenue avant même que le serveur ne soit contacté.

Certaines des situations courantes qui produisent ce code d'état sont reflétées dans les autres réponses, mais il peut s'agir de l'un ou de aucun de ces problèmes:

  1. Demande d'origine croisée illégale (voir CORS )
  2. Blocage ou filtrage du pare-feu
  3. La demande elle-même a été annulée dans le code
  4. Une extension de navigateur installée gâche les choses

Ce qui serait utile pour les navigateurs serait de fournir des rapports d'erreur détaillés pour plus de ces scénarios de statut == 0. En effet, parfois status == 0 accompagnera un message de console utile, mais dans d'autres il n'y a pas d'autres informations.

Whitneyland
la source
4
L'addon Firefox NoScript peut annuler la requête XHR aux hôtes non approuvés.
Ivan Solntsev
5
+ 1, tout cela est exact et "une sorte d'erreur s'est produite" est l'interprétation pratique. Pour les personnes intéressées par une liste complète des causes possibles données par la spécification, j'ai publié une ventilation sur stackoverflow.com/a/26451773/1709587 .
Mark Amery
1
Parmi les cas détaillés par Mark Amery qui me causent le plus de problèmes, il y a le cas des cors. Si l'erreur entraîne l'échec de la réponse à la validation de cors, vous obtiendrez un statut 0 au lieu de l'état http, car lorsque la validation de cors échoue, la réponse n'est pas accessible. Particulièrement frustrant lorsque vous essayez de détecter une API Web en cours de maintenance et de répondre 503. Si cette API n'honore pas les cors pendant la maintenance, vous ne pourrez pas détecter le 503, vous obtiendrez simplement 0, ce qui peut être causé par tant d'autres des choses.
Frédéric
Problème CORS auquel j'ai été confronté: envisagez d'utiliser httpplutôt que httpssi votre page a été initialement chargée httpet vice versa. Un autre mot n'effectue pas ajax POSTvia httpssi votre page a été accédée via httpet n'effectue pas ajax POSTvia httpsi votre page a été initialement accédée via https.
Victor Ponamarev
Les requêtes synchrones lancent une exception plus significative sur l'état 0: stackoverflow.com/a/49573256/1192811
McX
35

Pour ce que cela vaut, selon le navigateur, les appels AJAX basés sur jQuery appelleront votre rappel de réussite avec un code d'état HTTP de 0. Nous avons trouvé un code d'état de "0" signifie généralement que l'utilisateur a navigué vers une page différente avant l'appel AJAX terminé.

Pas la même pile technologique que celle que vous utilisez, mais j'espère qu'elle sera utile à quelqu'un.

Cory R. King
la source
Oui, les gens sont probablement souvent confrontés à ce problème, car cette page a été consultée 10 000 fois.
mike nelson
Ou devrais-je dire 25 000 vues?
mike nelson
3
Cela vaut beaucoup: c'est exactement ce qui a échoué dans mes tests automatisés. Merci beaucoup!
alexfernandez
J'ai voté non parce que c'est "la" bonne réponse, mais c'est ce qui s'est passé dans mon cas.
Juan Mendes
Cela se produit certainement, mais ce n'est pas la seule raison pour laquelle vous verrez le code d'erreur == 0. vous ne pouvez pas supposer que c'est simplement l'utilisateur qui s'éloigne et donc filtrer les messages d'erreur de ce type.
wal
14

wininet.dll renvoie les codes de statut standard et non standard répertoriés ci-dessous.

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

Pour le code d'état "zéro", essayez-vous de faire une requête sur une page Web locale fonctionnant sur un serveur Web ou sans serveur Web?

XMLHttpRequest status = 0 et XMLHttpRequest statusText = unknown peuvent vous aider si vous n'exécutez pas votre script sur un serveur Web.

Christophe Eblé
la source
Merci pour les codes. Non, ce n'est pas une requête locale, c'est une requête adressée à un serveur Web sur Internet, à partir d'un vbscript exécuté localement.
mike nelson
6

Solution de contournement: ce que nous avons fini par faire

Nous avons pensé que c'était à voir avec des problèmes de pare-feu, et nous avons donc trouvé une solution de contournement qui a fait l'affaire. Si quelqu'un a le même problème, voici ce que nous avons fait:

  1. Nous écrivons toujours les données dans un fichier texte sur le disque dur local comme nous l'avons fait précédemment, en utilisant un HTA.

  2. Lorsque l'utilisateur clique sur "renvoyer les données au serveur", le HTA lit les données et écrit une page HTML qui inclut ces données comme un îlot de données XML (en utilisant en fait un bloc de script SCRIPT LANGUAGE = XML).

  3. Le HTA lance un lien vers la page HTML dans le navigateur.

  4. La page HTML contient maintenant le javascript qui publie les données sur le serveur (à l'aide de Microsoft.XMLHTTP).

J'espère que cela aide toute personne ayant une exigence similaire. Dans ce cas, il s'agissait d'un jeu Flash utilisé sur un ordinateur portable lors de salons. Nous n'avons jamais eu accès à l'ordinateur portable et ne pouvions que l'envoyer par e-mail au client car ce salon se déroulait dans un autre pays.

Mike Nelson
la source
Bonjour, j'étudie un problème similaire qui se produit chez un client en production. Vous dites que le problème pour vous a été causé par un pare-feu. Vous rappelez-vous quel a été l'effet causé par le pare-feu, ou qu'est-ce que le pare-feu a fait pour provoquer cela?
Ibrahim Najjar
5

Un code de réponse HTTP de 0 indique que la requête AJAX a été annulée.

Cela peut se produire à partir d'un délai d'expiration, d'un avortement XHR ou d'un pare-feu piétinant la demande. Un délai d'expiration est courant, cela signifie que la demande n'a pas pu s'exécuter dans un délai spécifié. Un avortement XHR est très simple à faire ... vous pouvez en fait appeler .abort () sur un objet XMLHttpRequest pour annuler l'appel AJAX. ( C'est une bonne pratique pour une application à page unique si vous ne voulez pas que les appels AJAX reviennent et tentent de référencer des objets qui ont été détruits. ) Comme mentionné dans la réponse marquée, un pare-feu serait également capable d'annuler la demande et de déclencher cette 0 réponse.

Abandon XHR: abandonner les requêtes Ajax à l'aide de 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()

Il convient de noter que l'exécution de la méthode .abort () sur un objet XHR déclenchera également le rappel d'erreur. Si vous effectuez une gestion d'erreur qui analyse ces objets, vous remarquerez rapidement qu'un XHR abandonné et un XHR de délai d'expiration sont identiques, mais avec jQuery, le textStatus qui est passé au rappel d'erreur sera "abandonné" en cas d'abandon. et "timeout" avec un timeout se produit. Si vous utilisez Zepto (très très similaire à jQuery), le errorType sera "error" en cas d'abandon et "timeout" quand un timeout se produit.

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

Comme détaillé par cette réponse sur cette page , un code d'état de 0 signifie que la demande a échoué pour une raison quelconque, et une bibliothèque javascript a interprété l'échec comme un code d'état de 0.

Pour tester cela, vous pouvez effectuer l'une des opérations suivantes:

1) Utilisez cette extension chrome, Requestly pour rediriger votre URL de la httpsversion de votre URL vers la httpversion, car cela provoquera une erreur de sécurité de contenu mixte et générera finalement un code de statut de 0. L'avantage de cette approche est que vous ne Vous n'avez pas du tout à changer votre application, et vous pouvez simplement "réécrire" votre URL en utilisant cette extension.

2) Changez le code de votre application pour éventuellement rediriger votre point de terminaison vers la httpversion de votre URL au lieu de la httpsversion (ou vice versa). Si vous faites cela, la demande échouera avec le code d'état 0.

Brad Parks
la source
1
"Utiliser cette extension Chrome" - Une extension Chrome? Dans une application HTA?
Quentin
4
Bon point c'est sûr! Mais la plupart des gens qui arrivent ici ne viennent pas ici pour les applications HTA. Ils recherchent sur Google "javascript http status code 0" ou quelque chose comme ça, et arrivent ici - donc je pense que la partie HTA de cette question est de la moindre importance, dans l'ensemble, et finalement c'est toujours d'actualité.
Brad Parks
2

Dans mon cas, le statut est devenu 0 lorsque j'oublierais de mettre le WWW devant mon domaine. Parce que toutes mes demandes ajax étaient codées en dur http: /WWW.mydomain.com et que la page Web chargée serait juste http://mondomaine.com, cela devenait un problème de sécurité car il s'agissait d'un domaine différent. J'ai fini par faire une redirection dans mon fichier .htaccess pour toujours mettre www devant.

compatriotes du monde
la source
1

Dans mon cas, c'était parce que l'appel AJAX était bloqué par le navigateur en raison de la politique de même origine . C'était la chose la moins attendue, parce que tous mes HTML et scripts étaient servis 127.0.0.1. Comment pourraient-ils être considérés comme ayant des origines différentes?

Quoi qu'il en soit, la cause première était une <base>balise d' apparence innocente :

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

J'ai supprimé la <base>balise, dont je n'avais pas besoin d'ailleurs, et maintenant ça marche bien!

Saintali
la source
1

J'ai trouvé une raison nouvelle et non documentée pour le statut == 0. Voici ce que j'avais:

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

Il n'était pas d'origine croisée, réseau ou en raison de demandes annulées (par code ou par navigation utilisateur). Rien dans la console développeur ou dans le journal réseau.

Je n'ai pu trouver que très peu de documentation sur state () (Mozilla ne le répertorie pas, le W3C le fait) et rien de tout cela ne mentionne «rejeté».

Il s'avère que c'était mon bloqueur de publicité (uBlock Origin sur Firefox).

Jonathan Amend
la source
1

En plus de la réponse de Lee , vous pouvez trouver plus d'informations sur la cause réelle en passant aux requêtes synchrones , car vous obtiendrez également une exception:

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

Par exemple :

NetworkError: une erreur réseau s'est produite.

McX
la source
0

Au cas où quelqu'un d'autre rencontrerait ce problème, cela me posait des problèmes en raison de la demande AJAX et d'une demande de formulaire normale envoyée. Je l'ai résolu avec la ligne suivante:

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

La clé est le return false, qui empêche l'envoi du formulaire. Vous pouvez aussi simplement renvoyer false de l'intérieur de submitfunc (), mais je trouve que l'écrire explicitement est plus clair.

Samoz
la source
1
Prevent Default fonctionne également pour cela. C'est une fonction javascript qui empêche le navigateur d'exécuter le comportement par défaut pendant les événements, ce qui vous permet de remplacer / empêcher proprement la fonctionnalité native ... return false fait la même chose aussi.
Cory Danielson
0

Il convient de noter qu'un téléchargement de fichier ajax dépassant la client_max_body_sizedirective pour nginx renverra ce code d'erreur.

r3wt
la source
0

Si vous testez sur un PC local, cela ne fonctionnera pas. Pour tester l'exemple Ajax, vous devez placer les fichiers HTML sur un serveur Web.

ExcelinEfendisi
la source
0

Dans mon cas, l'erreur s'est produite dans une page demandée avec le protocole HTTP, avec un Javascript à l'intérieur essayant de faire une requête HTTPS. Et vice versa.

Après le chargement de la page, appuyez sur F12 (ou Ctrl + U) et regardez le code HTML de votre page. Si vous voyez quelque chose comme ça dans votre code:

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

Et votre page a été demandée de cette façon:

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

Vous serez certainement confronté à cette erreur.

Pour y remédier, définissez le protocole de la requête Javascript égal au protocole de la requête de page.

Cette situation impliquant différents protocoles, pour les requêtes page et js, a déjà été mentionnée dans la réponse de Brad Parks mais, je suppose que la technique de diagnostic présentée ici est plus facile, pour la majorité des utilisateurs.

aldemarcalazans
la source