Les demandes jQuery Ajax sont annulées sans être envoyées

87

J'essaie de connecter un script à l'application World-Wide Telescope de Microsoft. Ce dernier écoute sur le port 5050 les commandes. Il fonctionne sur la même machine que le navigateur (Chrome en ce moment, mais pour autant que je sache, le comportement est le même avec Firefox 7 et IE 9).

J'envoie un en-tête "Access-Control-Allow-Origin: *" avec le fichier html d'origine pour essayer d'éliminer les restrictions XSS en tant que problème.

Mon code pour accéder à WWT est le suivant:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    crossDomain: true,
    success: success,
    dataType: dataType
});

url dans ce cas est "http: //127.0.0.1: 5050 / layerApi.aspx? cmd = new & ..." (évidemment ... est ici un raccourci pour quelques paramètres supplémentaires).

En regardant les diagnostics réseau dans Chrome, je peux voir ceci:

Request URL:http://127.0.0.1:5050/layerApi.aspx?cmd=new&...
Request Headersview source
Accept:application/xml, text/xml, */*; q=0.01
Content-Type:application/x-www-form-urlencoded
Origin:http://gwheeler4
Referer:http://gwheeler4/conceptconnect.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1

La demande sort - je vois que WWT crée une nouvelle couche. Cependant, je ne reçois pas de rappel. Si j'ajoute un rappel d'erreur qui est appelé, mais que la propriété error sur l'objet jqXHR est simplement "error" et que le statut est 0. Si je regarde la demande réseau dans Chrome, je vois "(annulé)" comme état et pas de réponse .

Si je prends cette même URL et la colle dans un nouvel onglet de navigateur, je peux voir que la réponse est le XML attendu.

Bien sûr, une différence ici est qu'il s'agit d'un GET et non d'un POST, mais j'ai essayé cela dans mon script et cela ne fait aucune différence.

Je suis assez perplexe et j'apprécierais toute nouvelle idée.

Graham Wheeler
la source
Avez-vous essayé de gérer le errorrappel pour voir s'il revient avec une erreur?
StriplingWarrior
1
"J'envoie un en-tête" Access-Control-Allow-Origin: * "avec le fichier html d'origine pour essayer d'éliminer les restrictions XSS en tant que problème." Voulez-vous dire que le serveur renvoie l'en-tête Access-Control-Origin? Ou que vous l'envoyez avec la demande Ajax?
Jason Dean
essayez d'accéder à la page directement via l'URL et voyez-vous en sortir
zod
1
Oui, j'obtiens un rappel d'erreur avec le texte d'état "" et le code 0. Ce n'est pas un problème jQuery; J'ai réécrit le code en utilisant un XHR simple et j'obtiens le même résultat - c'est-à-dire un readyState de 4 avec un request.status de zéro et un request.responseText vide. L'en-tête Access-Control-Allow-Origin est envoyé par le serveur. L'accès à la page directement via l'URL renvoie la réponse XML attendue.
Graham Wheeler

Réponses:

134

Si quelqu'un d'autre rencontre cela, le problème que nous avions était que nous faisions la requête ajax à partir d'un lien, et n'empêchait pas le lien d'être suivi. Donc, si vous faites cela dans un onclickattribut, assurez-vous de le faire return false;également.

Kazetsukai
la source
Cela a fonctionné pour moi aussi. Merci. J'ai oublié pourquoi je retournais false dans mon gestionnaire onClick, et je l'ai changé en true, et après avoir lu votre message, cela m'est soudainement apparu.
Shiprack
4
En outre, si vous utilisez un formulaire, vous devez ajouter l' attribut return falseà la fin de votre onsubmit.
Jason Axelson
8
@VincentClyde "return false;"indique aux formulaires et aux liens d'abandonner l'action. Cela était à l'origine destiné à la validation de formulaire javascript, où une fonction de validation renverrait false si le formulaire n'était pas valide, empêchant le formulaire de se soumettre.
Tyzoid
13
Vous pouvez également utiliser e.preventDefault();, où eest le onclickparamètre d'événement.
Hannele
1
@Hannele Merci beaucoup d'avoir partagé event.preventDefault. J'en avais tellement besoin. Je ne vois aucune autre réponse suggérant cela. Vous devriez poster ceci comme réponse séparée.
Mohit
112

Si vous utilisez Chrome, vous ne pouvez pas voir suffisamment d'informations dans le panneau de mise en réseau Chrome standard pour déterminer la cause première d'une (canceled)demande.

Vous devez utiliser chrome://net-internals/#eventsce qui vous montrera les détails sanglants de la demande que vous envoyez - y compris les redirections cachées / les informations de sécurité sur les cookies envoyés, etc.

Par exemple, ce qui suit montre une redirection que je ne voyais pas dans la trace réseau - causée par le fait que mes cookies ne sont pas envoyés entre les sous-domaines:

t=1374052796448 [st=  1]   +URL_REQUEST_START_JOB  [dt=261]
                            --> load_flags = 143540481 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                            --> method = "GET"
                            --> priority = 2
                            --> url = "https://...."
...
t=1374052796708 [st=261]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                --> HTTP/1.1 302 Moved Temporarily
                                    Content-Type: text/html
                                    Date: Wed, 17 Jul 2013 09:19:56 GMT
...
t=1374052796709 [st=262]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=0]
t=1374052796709 [st=262]        CANCELLED
t=1374052796709 [st=262]   -URL_REQUEST_START_JOB
                            --> net_error = -3 (ERR_ABORTED)
Ben Walding
la source
J'ai aussi un problème (annulé). @Ben, c'était cool d'en savoir plus sur cette trace, malheureusement elle n'a fourni aucune info. Le serveur dans mon cas est S3 et cors est configuré sur mon compartiment. Tout ce que je fais, c'est un simple GET pour une image. Je vois dans un panneau réseau une requête avec l'en-tête Origin, mais aucune réponse. Apparemment, Chrome annule la demande avant de l'envoyer au serveur. Pas de redirections, pas de https, pas de contenu-longueur 0. Me frapper la tête toute la journée, encore un mystère.
Gene Vayngrib
@GeneVayngrib Essayez Firefox - le débogueur réseau affichera directement plus d'informations - vous pourrez peut-être résoudre le problème là-bas, puis le faire fonctionner dans Chrome.
Ben Walding
@BenW merci, mais Firefox n'a aucun problème avec cette image qui est servie depuis Amazon S3.
Gene Vayngrib
YUPP. Cela a beaucoup aidé!
rubmz
21

Dans mon cas, je l'avais type='submit'alors lorsque je soumettais le formulaire, la page se rechargeait avant que l'ajax ne se déclenche, donc une solution simple était d'avoir type="button". Si vous ne spécifiez pas de type, c'est submitpar défaut, vous devez donc spécifiertype="button"

type='submit' => type='button'

OU

Aucun type => type='button'

Black Mamba
la source
3
necro postant ici, poursuivez-moi stackoverflow. J'ai cherché haut et bas toute la journée pourquoi ma requête fonctionne depuis la console mais pas le script, et c'était la réponse .. merci !!!
pcort
1
Je me suis connecté et j'ai trouvé à nouveau ce fil pour voter pour cette réponse !!, cela a beaucoup aidé. me cassait la tête pendant des heures
dev
Jai shree krishna, j'espère que cela aidera beaucoup à venir. Et ils découvrent plus tôt.
Black Mamba le
6

J'avais un problème similaire. Dans mon cas, j'essaye d'utiliser un service web sur un serveur apache + django (le service a été écrit par moi-même). J'avais le même résultat que vous: Chrome dit qu'il a été annulé tandis que FF le fait bien. Si j'essayais d'accéder au service directement sur le navigateur au lieu d'ajax, cela fonctionnerait également. En cherchant sur Google, j'ai découvert que certaines versions plus récentes d'Apache ne définissaient pas correctement la longueur de la réponse dans les en-têtes de réponse, alors je l'ai fait manuellement. Avec django, tout ce que j'avais à faire était:

response['Content-Length'] = len(content)

Si vous contrôlez le service auquel vous essayez d'accéder, découvrez comment modifier l'en-tête de réponse dans la plate-forme que vous utilisez, sinon vous devrez contacter le fournisseur de services pour résoudre ce problème. Apparemment, FF et de nombreux autres navigateurs sont capables de gérer cette situation correctement, mais les concepteurs de Chrome ont décidé de le faire comme spécifié.

Felipe Sodre Silva
la source
J'ai essayé de définir l'en-tête de longueur de contenu et j'ai toujours le même problème que celui décrit dans la question d'origine. J'utilise PHP 5.3.8 et Apache 2.2.21 (en utilisant WAMP sous Windows 7)
rodrigo-silveira
4

J'ai eu un problème similaire. En utilisant chrome: // net-internals / # events, j'ai pu voir que mon problème était dû à une redirection silencieuse. Ma demande d'obtention était lancée dans un script onload. L'URL était de la forme " http://example.com/inner-path " et le 301 redirigeait en permanence vers "/ inner-path". Pour résoudre le problème, je viens de changer l'URL en "/ inner-path" et cela a résolu le problème. Je ne sais toujours pas pourquoi un script qui a fonctionné il y a une semaine m'a soudainement posé problème ... J'espère que cela aide quelqu'un

RedEight
la source
3

(Utilisation de Web Forms ASP.NET)

Mon problème était que j'essayais de déclencher Ajax sur l'événement de clic d'un bouton de soumission qui avait une configuration d'événement de clic côté serveur. J'ai dû faire du bouton juste un simple bouton (ie <input type="button">)

contactmatt
la source
Merci beaucoup.
Farheen Nilofer
3

J'ai eu le même problème, pour moi, je créais l'iframe de manière temporaire et je supprimais l'iframe avant que l'ajax ne se termine, donc le navigateur annulait ma demande ajax.

Reza
la source
Comment avez-vous résolu ce problème? Mon site est en train d'être intégré dans un iFrame non contrôlé par moi.Je veux que mon appel soit terminé car il fait certains paramètres de données d'arrière-plan
Rips
@Rips c'est il y a 4 ans, de toute façon je pense que je l'ai résolu en utilisant Promises
Reza
3

En développant la réponse de @ Kazetsukai, vous pouvez rencontrer ce problème si vous faites votre demande AJAX de l'utilisateur cliquant sur un lien.

Si vous configurez votre lien comme ceci:

<a href="#" onclick="soAjax()">click me!</a>

Et puis un gestionnaire javascript comme le suivant:

soAjax() {
    $.ajax({ ... all your lovely parameters ... });       
}

Pour empêcher votre navigateur de suivre le lien et d'annuler les demandes en cours, vous devez ajouter return false ou e.preventDefault()arrêter la propagation de l'événement de clic:

soAjax() {
   $.ajax({ ... etc ... });
   return false;
}

Ou:

soAjax(e) {
   $.ajax({ ... etc ... });
   e.preventDefault();
}
Hannele
la source
2

Deux possibilités existent lorsque la requête AJAX est abandonnée (si ce n'est pas la requête Cross-Origin):

  1. Vous n'empêchez pas le comportement par défaut de l'élément pour l'événement.
  2. Vous définissez le délai d'expiration d'AJAX trop bas ou le serveur principal du réseau / application est lent.

Solution pour 1) : Ajoutez return false;ou e.preventDefault();dans le gestionnaire d'événements.

Solution pour 2) : Ajouter une option de délai lors de la formation de la requête AJAX. Exemple ci-dessous.

$.ajax({
    type: 'POST',
    url: url,
    timeout: 86400,
    data: data,
    success: success,
    dataType: dataType
});

Pour les demandes cross-origin, vérifiez les en-têtes HTTP CORS (Cross-Origin Resource Sharing).

AnkitK
la source
1

J'ai eu cette erreur lors d'une demande via http vers une URL nécessitant https. Je suppose que l'appel ajax ne gère pas la redirection. C'est le cas même avec l'option ajax crossDomain définie sur true (sur JQuery 1.5.2).

ptutt
la source
0

Dans mon cas, le mod-rewrite d'Apache correspondait à l'url et redirigeait la demande vers https.

Regardez la requête dans chrome: // net-internals / # events.

Il affichera un journal interne de la demande. Vérifiez les redirections.

bbrame
la source
0

J'ai eu le même problème, mais dans mon cas, il s'est avéré être un problème de cookies. Les gars travaillant sur le back-end avaient changé le chemin du cookie JSESSIONID qui est défini lorsque nous nous connectons à notre application, et j'avais un ancien cookie de ce nom sur mon ordinateur, mais avec l'ancien chemin. Ainsi, lorsque j'ai essayé de me connecter au navigateur (Chrome), j'ai envoyé deux cookies appelés JSESSIONID, avec des valeurs différentes, au serveur - ce qui l'a naturellement confondu - il a donc annulé la demande. La suppression des cookies de mon ordinateur a résolu le problème.

Joe Dyndale
la source
0

J'ai eu cette erreur d'une manière plus effrayante: l'onglet réseau et les événements chrome: // net-internals / # n'ont pas montré la demande une fois le js terminé. Lors de la mise en pause des js dans le callcack d'erreur, l'onglet réseau a montré la demande comme (annulée). Le a toujours été appelé pour exactement une (toujours la même) de plusieurs demandes similaires dans une page Web. Après avoir redémarré Chrome, l'erreur ne s'est pas reproduite!

Christian
la source
0

J'ai eu l' annulation dans Firefox . Certains appels ajax fonctionnent parfaitement bien pour moi, mais cela a échoué pour le collègue qui a dû l'utiliser.

Lorsque j'ai vérifié cela via les astuces Chrome mentionnées ci-dessus, je n'ai rien trouvé de suspect. Lors de sa vérification dans Firebug, il a montré l'animation de 'chargement' après les deux appels mallicous, et aucun onglet de résultat.

La solution était très simple: aller à l'historique, trouver le site Web, faire un clic droit -> oublier le site Web.
Oubliez, ne supprimez pas.

Après cela, plus de problèmes. Je suppose que cela a quelque chose à voir avec le .htaccess.

Martijn
la source
0

Dans mon cas, c'était la barre oblique manquante dans l'URL. L'ajout de la barre oblique de fin a résolu mon problème.

Aftab Baig
la source
0

Pour le cas de Dropzone.js. Dans mon cas, cela est dû au fait que la valeur de l' timeoutoption était trop faible par défaut. Alors augmentez-le selon vos besoins.

{
// other dropzone options
timeout: 60000 * 10, // 10 minutes
...
}
Scofield
la source
-1

J'ai eu ce problème avec un réseau 3G particulier.
Il échouerait toujours sur les requêtes DELETE avec des net_error = -101événements chrome: // net-internals / #.

D'autres réseaux fonctionnaient très bien, donc je suppose qu'il y avait un serveur proxy défectueux ou quelque chose du genre.

Dan Abramov
la source