Un code de statut HTTP de 0 a-t-il une signification?

91

Il semble que lorsque vous effectuez une requête XMLHttpRequest à partir d'un script dans un navigateur, si le navigateur est configuré pour fonctionner hors ligne ou si le câble réseau est débranché, la requête se termine avec une erreur et avec un statut = 0. 0 n'est pas répertorié parmi les permis Codes d'état HTTP.

Que signifie un code d'état de 0? Cela signifie-t-il la même chose pour tous les navigateurs et pour tous les utilitaires clients HTTP? Cela fait-il partie de la spécification HTTP ou fait-il partie d'une autre spécification de protocole? Cela semble signifier que la requête HTTP n'a pas pu être effectuée du tout, peut-être parce que l'adresse du serveur n'a pas pu être résolue.

Quel message d'erreur convient-il d'afficher à l'utilisateur? "Soit vous n'êtes pas connecté à Internet, soit le site Web rencontre des problèmes, soit il peut y avoir une erreur de saisie dans l'adresse"?

Je devrais ajouter à cela que je vois le comportement dans FireFox lorsqu'il est réglé sur "Work Offline", mais pas dans Microsoft Internet Explorer lorsqu'il est réglé sur "Work Offline". Dans IE, l'utilisateur obtient une boîte de dialogue lui donnant la possibilité d'aller en ligne. FireFox n'informe pas l'utilisateur avant de renvoyer l'erreur.

Je demande ceci en réponse à une demande de "montrer un meilleur message d'erreur". Ce que fait Internet Explorer est bon. Il indique à l'utilisateur la cause du problème et lui donne la possibilité de le résoudre. Afin de donner une expérience utilisateur équivalente avec FireFox, je dois déduire la cause du problème et informer l'utilisateur. Alors, que puis-je déduire au total du statut 0? At-elle une signification universelle ou ne me dit-elle rien?

Mark Lutton
la source
Veuillez consulter cette question, qui couvre le même sujet: stackoverflow.com/questions/872206/…
Scott Stafford
3
Je crois que c'est la réponse la plus précise: stackoverflow.com/a/14507670/700206
whitneyland
Un autre article connexe - Que signifie le code d'état HTTP 0
RBT

Réponses:

153

Réponse courte

Ce n'est pas un code de réponse HTTP, mais il est documenté par WhatWG comme une valeur valide pour l'attribut status d'une XMLHttpRequestou d'une réponse Fetch.

D'une manière générale, il s'agit d'une valeur par défaut utilisée lorsqu'il n'y a pas de véritable code d'état HTTP à signaler et / ou qu'une erreur s'est produite lors de l'envoi de la requête ou de la réception de la réponse. Les scénarios possibles dans lesquels tel est le cas incluent, mais sans s'y limiter:

  • La demande n'a pas encore été envoyée ou a été abandonnée.
  • Le navigateur attend toujours de recevoir l'état de la réponse et les en-têtes.
  • La connexion a été interrompue pendant la demande.
  • La demande a expiré.
  • La demande a rencontré une boucle de redirection infinie.
  • Le navigateur connaît l'état de la réponse, mais vous n'êtes pas autorisé à y accéder en raison de restrictions de sécurité liées à la politique de même origine .

Longue réponse

Tout d'abord, pour réitérer: 0 n'est pas un code d'état HTTP. Il y en a une liste complète dans la RFC 7231 Section 6.1 , qui n'inclut pas 0, et l'intro de la section 6 indique clairement que

L'élément status-code est un code entier à trois chiffres

lequel 0 n'est pas.

Cependant, 0 en tant que valeur de l' .statusattribut d'un objet XMLHttpRequest est documenté, bien qu'il soit un peu difficile de retrouver tous les détails pertinents. Nous commençons à https://xhr.spec.whatwg.org/#the-status-attribute , documentant l' .statusattribut, qui déclare simplement:

L' statusattribut doit retourner la réponse de » statut .

Cela peut sembler vide et tautologique, mais en réalité, il y a des informations ici! Rappelez-vous que cette documentation parle ici de l' .responseattribut d'une XMLHttpRequestréponse, pas d'une réponse, donc cela nous indique que la définition du statut d'un objet XHR est reportée à la définition du statut d'une réponse dans la spécification Fetch.

Mais quel objet de réponse? Et si nous n'avons pas encore reçu de réponse? Le lien en ligne sur le mot «réponse» nous amène à https://xhr.spec.whatwg.org/#response , ce qui explique:

An XMLHttpRequesta une réponse associée. Sauf indication contraire, il s'agit d'une erreur réseau .

Donc, la réponse dont nous obtenons le statut est par défaut une erreur réseau. Et en recherchant partout où l'expression "définir la réponse à" est utilisée dans la spécification XHR, nous pouvons voir qu'elle est définie à cinq endroits:

En regardant dans la norme Fetch , nous pouvons voir que:

Une erreur réseau est une réponse dont l' état est toujours0

afin que nous puissions immédiatement dire que nous verrons un état de 0 sur un objet XHR dans tous les cas où la spécification XHR indique que la réponse doit être définie sur une erreur réseau. (Fait intéressant, cela inclut le cas où le flux du corps est "erroné", ce qui, selon la spécification Fetch, peut se produire lors de l'analyse du corps après avoir reçu le statut - donc en théorie, je suppose qu'il est possible qu'un objet XHR ait son statut mis à 200, puis rencontrez une erreur de mémoire insuffisante ou quelque chose lors de la réception du corps et modifiez ainsi son état à 0.)

Nous notons également dans la norme Fetch qu'il existe quelques autres types de réponse dont le statut est défini comme étant 0, dont l'existence est liée aux demandes d'origine croisée et à la politique de même origine:

Une réponse filtrée opaque est une réponse filtrée dont le statut 0... est ...

Une réponse filtrée par redirection opaque est une réponse filtrée dont le statut 0... est ...

(divers autres détails sur ces deux types de réponse ont été omis).

Mais au-delà de cela, il existe également de nombreux cas où l' algorithme Fetch (plutôt que la spécification XHR, que nous avons déjà examinée) appelle le navigateur à renvoyer une erreur réseau! En effet, l'expression "renvoyer une erreur réseau" apparaît 40 fois dans le standard Fetch. Je n'essaierai pas de lister les 40 ici, mais je note qu'ils comprennent:

  • Le cas où le schéma de la requête n'est pas reconnu (par exemple en essayant d'envoyer une requête à madeupscheme: //foobar.com)
  • L'instruction merveilleusement vague "En cas de doute, renvoyez une erreur réseau." dans les algorithmes de gestion des URL ftp: // et file: //
  • Redirections infinies: "Si le nombre de redirections de la requête est de vingt, renvoie une erreur réseau."
  • Un tas de problèmes liés à CORS, tels que "Si la réponse de httpRequest n'est pas" cors "et la vérification de la politique de ressources inter-origines avec les retours de demande et de réponse bloqués, puis renvoie une erreur réseau."
  • Échecs de connexion: «Si la connexion échoue, renvoie une erreur réseau».

En d'autres termes: chaque fois que quelque chose ne va pas autre que d'obtenir un vrai code d'état d'erreur HTTP comme un 500 ou 400 du serveur, vous vous retrouvez avec un attribut d'état de 0 sur votre objet XHR ou l'objet de réponse Fetch dans le navigateur. Le nombre de causes spécifiques possibles énumérées dans les spécifications est vaste.

Enfin: si vous êtes intéressé par l'historique de la spécification pour une raison quelconque, notez que cette réponse a été complètement réécrite en 2020, et que vous pourriez être intéressé par la révision précédente de cette réponse , qui a analysé essentiellement les mêmes conclusions de la les spécifications W3 plus anciennes (et beaucoup plus simples) pour XHR, avant qu'elles ne soient remplacées par les spécifications WhatWG plus modernes et plus compliquées auxquelles ces réponses font référence.

Mark Amery
la source
53

l'état 0 apparaît lorsqu'un appel ajax a été annulé avant d'obtenir la réponse en actualisant la page ou en demandant une URL inaccessible.

cet état n'est pas documenté mais existe sur les appels ajax et makeRequest depuis gadget.io.

mnk
la source
4
Bonjour, Existe-t-il un moyen de faire la différence entre une demande échouée ("Aucun réseau") et une demande annulée?
Ankur
2
Cet état est documenté comme étant un état XmlHttpRequest. Bien sûr, ce n'est pas un statut http, mais il est documenté. w3.org/TR/XMLHttpRequest/#the-status-attribute Voir la réponse de Mark Amery pour plus de détails.
Frédéric
4

Sachez que c'est un ancien message. Mais ces problèmes existent toujours.

Voici quelques-unes de mes découvertes sur le sujet, grossièrement expliquées.

"Statut" 0 signifie l'une des 3 choses, selon la spécification XMLHttpRequest:

  • La résolution du nom DNS a échoué (c'est par exemple lorsque la prise réseau est retirée)

  • le serveur n'a pas répondu (c'est-à-dire inaccessible ou sans réponse)

  • la demande a été abandonnée en raison d'un problème CORS (l'avortement est effectué par l'agent utilisateur et fait suite à un échec de pré-vol OPTIONS).

Si vous souhaitez aller plus loin, plongez-vous profondément dans les entrailles de XMLHttpRequest. Je suggère de lire la séquence de mise à jour de l'état prêt ([0,1,2,3,4] est la séquence normale, [0,1,4] correspond à l'état 0, [0,1,2,4] signifie pas de contenu envoyé qui peut être une erreur ou non). Vous pouvez également attacher des écouteurs au xhr (onreadystatechange, onabort, onerror, ontimeout) pour comprendre les détails.

À partir de la spécification ( XHR Living spec ):

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
la source
1
Toutes les causes possibles dans votre liste ici sont correctes, mais votre liste n'est pas exhaustive. Par exemple, vous manquez des délais d'attente, des boucles de redirection infinies et d'autres causes détaillées dans ma réponse . Cependant, le pointeur vers la nouvelle spécification XHR vivante est utile; Je devrais mettre à jour ma réponse pour citer cela au lieu de l'ancienne spécification W3.
Mark Amery
0

Depuis iOS 9, vous devez ajouter «Paramètres de sécurité du transport d'application» à votre fichier info.plist et autoriser «Autoriser les charges arbitraires» avant de faire une demande au service Web HTTP non sécurisé. J'ai eu ce problème dans l'une de mes applications.

Nirav
la source
-1

Oui, certains comment l'appel ajax a été abandonné. La cause peut être la suivante.

  1. Avant la fin de la demande ajax, l'utilisateur a accédé à une autre page.
  2. La demande Ajax a un délai d'expiration.
  3. Le serveur ne peut pas renvoyer de réponse.
Vinayak
la source