jQuery a désapprouvé XMLHTTPRequest synchrone

119

Comme beaucoup d'autres, mon site Web utilise jQuery. Lorsque j'ouvre les outils de développement, je vois un avertissement indiquant que XMLHTTPRequest est

obsolète en raison de ses effets néfastes sur l'expérience de l'utilisateur final.

J'ai continué et j'ai lu une partie de la documentation , mais c'était assez technique. Quelqu'un peut-il expliquer les conséquences du passage de XMLHTTPRequest à WHATWG en termes simples? Il dit que c'est arrivé en 2012.

En outre, la documentation indique que Synchronous XMLHttpRequest en dehors des nœuds de calcul est en cours de suppression de la plate-forme Web, lorsque cela se produit, si un agent utilisateur les avait dans un service, doit-il modifier son code existant?

Edd
la source
2
Vous devez parler de requêtes XMLHTTP synchrones, pas de requêtes asynchrones, n'est-ce pas? Les requêtes synchrones sont horribles pour l'expérience de l'utilisateur final (elles bloquent le navigateur pendant la requête) et ne doivent généralement pas être utilisées.
jfriend00
2
fournir du code qui déclenche cela
charlietfl
3
Est-ce le texte intégral en question? XMLHttpRequest synchrone sur le thread principal est obsolète en raison de ses effets néfastes sur l'expérience de l'utilisateur final.
Qantas 94 Heavy le
1
jQuery ne donne cet avertissement que pour les requêtes synchrones, n'est-ce pas? Faites-vous délibérément une demande synchrone? Si tel est le cas, la solution consiste à structurer votre code pour qu'il fonctionne avec des requêtes asynchrones, ce que vous devriez faire de toute façon car elles sont beaucoup plus agréables du point de vue de l'utilisateur.
nnnnnn
1
J'ai vu ce drapeau non seulement sur mon site Web, mais aussi dans d'autres, par exemple sur Youtube. En ce qui concerne les spécifications, avec quelles spécifications mon code doit-il être conforme, au W3C ou au WHATWG? , référence que je ne veux pas demander dans le fil principal car il serait signalé comme une question d'opinion, je suppose. @ Qantas94Heavy
Edd

Réponses:

136

Pour éviter cet avertissement, n'utilisez pas:

async: false

dans l'un de vos $.ajax()appels. C'est la seule fonctionnalité XMLHttpRequestobsolète.

La valeur par défaut est async: true, donc si vous n'utilisez jamais du tout cette option, votre code devrait être sûr si la fonctionnalité est vraiment supprimée.

Cependant, ce ne sera probablement pas le cas - il sera peut-être retiré des normes, mais je parie que les navigateurs continueront de le prendre en charge pendant de nombreuses années. Donc, si vous avez vraiment besoin d'AJAX synchrone pour une raison quelconque, vous pouvez utiliser async: falseet ignorer simplement les avertissements. Mais il y a de bonnes raisons pour lesquelles AJAX synchrone est considéré comme un style médiocre, vous devriez donc probablement essayer de trouver un moyen de l'éviter. Et les personnes qui ont écrit des applications Flash n'ont probablement jamais pensé que cela disparaîtrait non plus, mais il est en train d'être progressivement supprimé.

Notez que l' FetchAPI qui remplace XMLHttpRequestn'offre même pas d'option synchrone.

Barmar
la source
9
C'est donc l'avertissement de jQuery. Je peux l'ignorer? Je n'utilise pas d'appels synchrones vers le serveur. Le côté perfectionniste de moi n'aime pas du tout avoir des avertissements.
Jordanie
2
@Jordan Je pense que l'avertissement vient du navigateur, pas de jQuery. Cela se produira chaque fois que vous essayez d'utiliser AJAX synchrone. Si vous utilisez jQuery, cela ne se produira que si vous spécifiez cette option sur $.ajax.
Barmar
2
J'utilise jquery.i18n.properties.jsmais il n'y a pas d'appel explicite de mon côté à $.ajax.peut-être en interne, mais pas sûr.
Manuel Jordan
1
Ce plugin charge les ensembles de ressources à partir de .propertiesfichiers. Il utilise probablement AJAX synchrone pour le faire, ce qui provoque cet avertissement.
Barmar le
1
@ManuelJordan paramètre async: true dans i18n peut retarder l'affichage des chaînes affichées dans votre page en cas de connexion lente. Afficher à la place le code de chaîne
Siyon DP
62

La réponse acceptée est correcte, mais j'ai trouvé une autre cause si vous développez sous ASP.NET avec Visual Studio 2013 ou supérieur et êtes sûr que vous n'avez pas effectué de requêtes ajax synchrones ou défini des scripts au mauvais endroit.

La solution est de désactiver la fonction "Lien du navigateur" en décochant "Activer le lien du navigateur" dans la liste déroulante de la barre d'outils VS indiquée par la petite icône de rafraîchissement pointant dans le sens des aiguilles d'une montre. Dès que vous faites cela et rechargez la page, les avertissements devraient cesser!

Désactiver le lien du navigateur

Cela ne devrait se produire que lors du débogage local, mais il est toujours agréable de connaître la cause des avertissements.

Sam
la source
On peut désactiver dans web.configen ajoutant à l' <add key="vs:EnableBrowserLink" value="false" />intérieur <appSettings>comme décrit ici: poconosystems.com/software-development/... .
Beel
3
Je pense que c'est une mauvaise suggestion juste pour obtenir des messages d'avertissement dans la console. Désactiver le lien du navigateur et supprimer les améliorations de productivité ajoutées par le lien du navigateur afin que vous ne voyiez pas de message d'avertissement dans la console du navigateur? Mieux vaut déposer un bogue avec Microsoft et il est corrigé.
coding4fun
4
@ coding4fun Merci pour votre avis; vous pouvez vous sentir libre de déposer un bogue auprès de Microsoft. Je ne disais pas que vous devriez désactiver le lien du navigateur. Ma réponse est précise quant à la cause de cet avertissement dans certains cas et il est utile d'exclure quelque chose dans votre propre code. Personnellement, je me suis senti mieux une fois que j'ai réalisé que ce n'était pas quelque chose que je faisais de mal et que j'ai pensé que d'autres pourraient aussi trouver cela utile.
Sam
Cela a corrigé plus que l'avertissement ajax. J'ai toutes sortes de désordre de lien de navigateur dans la console javascript en utilisant asp core.
JoeBass
Quelqu'un saurait-il ce qu'est le lien du navigateur et pourquoi finit-il par donner un tel avertissement?
gideon
15

Cela m'est arrivé en ayant un lien vers des j externes à l'extérieur de la tête juste avant la fin de la section du corps. Vous savez, l'un de ceux-ci:

<script src="http://somesite.net/js/somefile.js">

Cela n'avait rien à voir avec JQuery.

Vous verriez probablement la même chose faire quelque chose comme ceci:

var script = $("<script></script>");
script.attr("src", basepath + "someotherfile.js");
$(document.body).append(script);

Mais je n'ai pas testé cette idée.

Dave ami
la source
L'avertissement est parti pour moi lorsque j'ai supprimé une ligne comme celle-ci, que je n'utilisais pas de toute façon: @ Html.Script ("~ / scripts / apps / appname.js")
MsTapp
10

Cela a été mentionné comme un commentaire par @ henri-chan , mais je pense que cela mérite plus d'attention:

Lorsque vous mettez à jour le contenu d'un élément avec un nouveau html à l'aide de jQuery / javascript, et que ce nouveau html contient des <script>balises, celles-ci sont exécutées de manière synchrone et déclenchent ainsi cette erreur. Il en va de même pour les feuilles de style.

Vous savez que cela se produit lorsque vous voyez (plusieurs) scripts ou feuilles de style en cours de chargement comme XHRdans la fenêtre de la console. (Firefox).

Hugo Delsing
la source
3

Aucune des réponses précédentes (qui sont toutes correctes) n'était adaptée à ma situation: je n'utilise pas le asyncparamètre dans jQuery.ajax()et je n'inclus pas de balise de script dans le contenu qui était renvoyé comme:

<div> 
     SOME CONTENT HERE
</div>
<script src="/scripts/script.js"></script> 

Ma situation est que j'appelle deux requêtes AJAX consécutivement dans le but de mettre à jour deux divs en même temps:

function f1() {
     $.ajax(...); // XMLHTTP request to url_1 and append result to div_1
}

function f2() {
     $.ajax(...); // XMLHTTP request to url_2 and append result to div_2
}

function anchor_f1(){
$('a.anchor1').click(function(){
     f1();
})
}

function anchor_f2(){
$('a.anchor2').click(function(){
     f2();
});
}

// the listener of anchor 3 the source of problem
function anchor_problem(){
$('a.anchor3').click(function(){
     f1();
     f2();
});
}

anchor_f1();
anchor_f2();
anchor_problem();

Lorsque je clique sur a.anchor3, cela déclenche le drapeau d'avertissement.J'ai résolu le problème en remplaçant f2 en invoquant par click()fonction:

function anchor_problem(){
$('a.anchor_problem').click(function(){
     f1();
     $('a.anchor_f2').click();
});
}
Adib Aroui
la source
5
Les scripts ne sont pas exécutés si vous les insérez directement dans le DOM via innerHTML. Ainsi, lorsque vous appelez .html (), jQuery récupère et exécute tous les scripts inclus dans la réponse html de manière synchrone.
Henry Chan
@HenryChan, j'ai essayé de vous comprendre mais en vain. Pourriez-vous s'il vous plaît m'expliquer avec des mots plus simples. Je n'insère pas de scripts dans le DOM, j'insère uniquement du HTML et cette solution reste la seule solution qui fonctionne pour moi. Merci d'avance
Adib Aroui
2
@whitelettersinblankpapers Je pense qu'il veut dire: dans votre callback ajax, si le contenu que vous ajoutez à vos "div" contient des balises de script, alors celles-ci seront appelées de manière synchrone.
Haitham Sweilem
1

Mon entraînement: j'utilise des requêtes asynchrones en vidant le code dans un tampon. J'ai une boucle vérifiant le tampon toutes les secondes. Lorsque le vidage est arrivé dans le tampon, j'exécute le code. J'utilise également un timeout. Pour l'utilisateur final, la page fonctionne comme si des requêtes synchrones étaient utilisées.

courir en arrière
la source
avez-vous un petit code pour que je sache comment y parvenir?
ZerOne
5
@runback, le rappel de promesse done () ne peut-il pas être utilisé? $.ajax({ url : "example.com", async : true /* default is true */ }).done(function(response){ // Process the dump }) J'espère que je n'ai rien mal lu.
pravin
0

Si nous chargeons le script en vue partielle, ce problème arrive

  1. J'ai supprimé le script en vue partielle et je suis passé à la vue principale.

Cette solution fonctionne bien pour moi

A.Chandrashekar shekar
la source