JavaScript console.log provoque une erreur: «Synchronous XMLHttpRequest sur le thread principal est obsolète…»

386

J'ai ajouté des journaux à la console pour vérifier l'état des différentes variables sans utiliser le débogueur Firefox.

Cependant, dans de nombreux endroits où j'ajoute un console.logdans mon main.jsfichier, je reçois l'erreur suivante au lieu de mes beaux petits messages manuscrits:

Synchronous XMLHttpRequest sur le thread principal est obsolète en raison de ses effets néfastes sur l'expérience de l'utilisateur final. Pour plus d'aide http://xhr.spec.whatwg.org/

Quelles alternatives ou wrappers pour console.logpuis-je ajouter à mon utilisation de code qui ne provoquera pas cette erreur?

Suis-je "en train de mal faire"?

Nathan Basanese
la source
8
Je ne vois pas comment un appel console.log () provoquerait un appel ajax, à moins qu'une sorte de plugin de journalisation à distance ne soit activé ou autre.
Marc B
Je ne suis pas sûr qu'il passe un appel ajax. Serait-il utile si j'incluais une capture d'écran?
Nathan Basanese
6
xmlhttprequest est une requête ajax, en gros.
Marc B
14
<script>$.ajaxPrefilter(function( options, originalOptions, jqXHR ) { options.async = true; });</script> cela supprimera l'avertissement. Vous pouvez voir ici pour le même problème.
Akilsree1
1
J'ai juste utilisé get au lieu de post, cela a aidé. jQuery.
Stas Kazanin du

Réponses:

278

Cela m'est arrivé lorsque j'étais paresseux et j'ai inclus une balise de script dans le contenu renvoyé. En tant que tel:

Contenu HTML partiel:

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

Il semble, au moins dans mon cas, que si vous renvoyez du contenu HTML comme celui-ci via xhr, vous demanderez à jQuery de faire un appel pour obtenir ce script. Cet appel se produit avec un indicateur asynchrone false car il suppose que vous avez besoin du script pour continuer le chargement.

Dans des situations comme celle-ci, vous seriez mieux servi en examinant un cadre de liaison quelconque et en renvoyant simplement un objet JSON, ou en fonction de votre backend et des modèles, vous pouvez changer la façon dont vous chargez vos scripts.

Vous pouvez également utiliser jQuerygetScript() pour récupérer des scripts pertinents. Voici un violon, c'est juste une copie directe de l'exemple jQuery, mais je ne vois aucun avertissement lancé lorsque les scripts sont chargés de cette façon.

Exemple

<script>
var url = "/scripts/script.js";
$.getScript(url);
</script>

http://jsfiddle.net/49tkL0qd/

kroolk
la source
8
l'erreur est due au fait que l'OP utilise quelque part un XMLHttpRequests synchrone, je ne pense pas que jquery car il ne semble pas qu'il l'utilise ... mais cela m'arrive quand j'essaie de charger un <script>comme vous l'avez dit dans un rappel d'un appel asynchrone ajax. Mon appel ajax est asynchrone mais dans le rappel que je fais $('#object').html(data)où les données sont un morceau de htmlavec <script>et lorsque cette ligne est exécutée l'erreur apparaît dans le js console. +1 !!! merci :).
albciff
2
Pour ce projet, j'ai en fait utilisé JQuery.
Nathan Basanese
1
@ 37coins, si telle était la réponse; marquez-le comme tel .. et remplacez la balise javascript par jQuery.
Brett Caswell
3
C'était mon problème, et probablement aussi le problème du PO - OP, veuillez considérer cela comme la réponse. La réponse la plus votée ici ne fait actuellement rien pour aider les gens avec ce problème, donc accepter cette réponse aiderait énormément les autres.
Nick Coad
1
juste FYI jQuery getScript rompt la mise en cache. Je pense que .ajax fera de même et permettra la mise en cache
Ronnie Royston
75

Le message d'avertissement PEUT ÊTRE dû à une demande XMLHttpRequest dans le thread principal avec l'indicateur async défini sur false.

https://xhr.spec.whatwg.org/#synchronous-flag :

Synchronous XMLHttpRequest en dehors des travailleurs est en train d'être supprimé de la plate-forme Web car cela a des effets néfastes sur l'expérience de l'utilisateur final. (Il s'agit d'un long processus qui prend de nombreuses années.) Les développeurs ne doivent pas passer false pour l'argument asynchrone lorsque l'environnement global JavaScript est un environnement de document. Les agents utilisateurs sont fortement encouragés à avertir d'une telle utilisation dans les outils de développement et peuvent expérimenter le lancement d'une exception InvalidAccessError lorsqu'elle se produit.

La direction future est d'autoriser uniquement XMLHttpRequests dans les threads de travail. Le message est destiné à être un avertissement à cet effet.

PedanticDan
la source
6
non, l'avertissement du message est VRAIMENT dû à une demande XMLHttpRequest dans le thread principal avec l'indicateur async défini sur false. Cela pourrait très bien être un bogue dans Firefox (mais c'est probablement une fonctionnalité / implémentation de jQuery); de toute façon, comment la description d'une partie de la spécification serait-elle considérée comme une réponse à une question qui, selon les allégations, console.logenvoie ces avertissements?
Brett Caswell
1
@Brett - les deux dernières phrases de ma réponse expliquent pourquoi j'ai inclus la partie de la spécification que j'ai faite. Je modifierai ma réponse pour être plus précis.
PedanticDan
2
avec tout ce qui a été dit, tout ce que vous avez déclaré dans cette réponse est une information correcte; en outre, il est probablement pertinent pour le problème probable; c'est-à-dire que le déclenchement de cet avertissement affecte le comportement et / ou la stabilité du débogueur. Ainsi, la solution de contournement peut très bien être d'empêcher l'avertissement de se déclencher en corrigeant la cause de celui-ci.
Brett Caswell
Ils doivent ajouter un indicateur about: pour l'activer pour le débogage local. Sync XHR peut être très utile pour les frameworks d'outillage / débogage exécutant localhost.
user2800679
62

J'étais également confronté au même problème, mais j'ai pu le résoudre en mettant async: true. Je sais que c'est par défaut vrai mais ça marche quand je l'écris explicitement

$.ajax({
   async: true,   // this will solve the problem
   type: "POST",
   url: "/Page/Method",
   contentType: "application/json",
   data: JSON.stringify({ ParameterName: paramValue }),
});
Irfan Ashraf
la source
2
Ce n'était pas la raison dans mon cas ... seulement en supprimant async: false sans changer en true fixe cela
hsobhy
@Irfan dans mon cas, il définissait la synchronisation: faux qui a aidé!
t_plusplus
34

Le débogueur en direct de Visual Studio 2015/2017 injecte du code qui contient l'appel obsolète.

Charlie
la source
13
J'ai passé pas mal de temps à essayer de comprendre pourquoi je voyais cet avertissement; J'ai pensé que je partagerais la question SO la plus appropriée pour que d'autres puissent gagner du temps.
Charlie
22

Parfois, il est nécessaire d'ajax charger un script mais de retarder le document prêt jusqu'à ce que le script soit chargé.

jQuery prend cela en charge avec la holdReady()fonction.

Exemple d'utilisation:

$.holdReady(true);                              //set hold
function releaseHold() { $.holdReady(false); }  //callback to release hold
$.getScript('script.js', releaseHold);          //load script then release hold

Le chargement réel du script est asynchrone ( pas d'erreur ), mais l'effet est synchrone si le reste de votre JavaScript s'exécute une fois le document prêt .

Cette fonctionnalité avancée est généralement utilisée par les chargeurs de scripts dynamiques qui souhaitent charger du JavaScript supplémentaire, comme les plug-ins jQuery, avant de permettre à l'événement ready de se produire, même si le DOM peut être prêt.

Documentation:
https://api.jquery.com/jquery.holdready


MISE À JOUR 7 janvier 2019

De JQMIGRATE :

jQuery.holdReady () est obsolète

Cause: la jQuery.holdReady()méthode est obsolète en raison de son effet néfaste sur les performances globales de la page. Cette méthode peut empêcher tout le code de la page de s'initialiser pendant des périodes prolongées.

Solution: réécrivez la page afin qu'elle ne nécessite pas de retarder tous les gestionnaires prêts pour jQuery. Cela peut être accompli, par exemple, en chargeant tardivement uniquement le code qui nécessite le délai lorsqu'il est sûr de s'exécuter. En raison de la complexité de cette méthode, jQuery Migrate ne tente pas de remplir la fonctionnalité. Si la version sous-jacente de jQuery utilisée avec jQuery Migrate ne contient plus, jQuery.holdReady()le code échouera peu de temps après l'apparition de cet avertissement.

Dem Pilafian
la source
17

Pour éviter cet avertissement, n'utilisez pas:

async: false

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

La valeur par défaut est

async: true

jQuery a déprécié le XMLHTTPRequest synchrone

Sonu K
la source
13

La réponse partielle @Webgr m'a effectivement aidé à déboguer cet avertissement @ journal de la console, dommage que l'autre partie de cette réponse ait apporté tant de votes négatifs :(

Quoi qu'il en soit, voici comment j'ai découvert quelle était la cause de cet avertissement dans mon cas:

  1. Utilisez le navigateur Chrome> Hit F12 pour apporter DevTools
  2. Ouvrez le menu du tiroir (dans Chrome 3 points verticaux en haut à droite)
  3. Sous Console > cochez l' option Log XMLHttpRequests
  4. Rechargez votre page qui vous a donné l'erreur et observez ce qui se passe à chaque demande ajax dans le journal de la console.

Dans mon cas, un autre plugin chargeait 2 bibliothèques .js après chaque appel ajax, qui n'étaient absolument pas nécessaires ni nécessaires. La désactivation du plugin escroc a supprimé l'avertissement du journal. À partir de là, vous pouvez soit essayer de résoudre le problème vous-même (par exemple, limiter le chargement des scripts à certaines pages ou événements - c'est beaucoup trop spécifique pour une réponse ici) ou contacter un développeur de plugin tiers pour le résoudre.

J'espère que cela aide quelqu'un.

dev101
la source
// , Merci d'avoir répondu! Cette question ne concernait que Firefox. Je suis intéressé de voir que cela s'est produit sur Chrome. Cela ne semble que supprimer l'avertissement, plutôt que de résoudre le problème. Est-ce exact?
Nathan Basanese
Il semble que Chrome possède des fonctionnalités plus avancées dans les DevTools que la version Firefox. Le fait qu'il ne soit pas signalé dans Firefox ne signifie pas qu'il n'est pas présent. Cela a complètement résolu mon problème, pas seulement caché. J'ai supprimé les scripts du plugin et de la page problématiques qui ont été «rechargés» à chaque appel ajax.
dev101
//, Pensez-vous que cela vaut la peine de soulever un problème avec les développeurs de Firefox?
Nathan Basanese
Non, pas nécessaire. Je viens de retester mon cas avec la dernière version de Firefox et l'avertissement "Synchronous XMLHttpRequest sur le thread principal ..." a également été signalé dans le journal de la console. Donc, ce n'était pas, du moins dans mon cas, un problème spécifique au navigateur. Maintenant, comment vous pouvez utiliser Firefox pour déboguer XMLHttpRequest via l'onglet Réseau, en regardant les ressources .js appelées après chaque demande ajax. Fait la même chose, bien qu'il soit plus rationalisé / filtré dans Chrome. developer.mozilla.org/en-US/docs/Tools/Network_Monitor
dev101
8

J'ai regardé les réponses toutes impressionnantes. Je pense qu'il devrait fournir le code qui lui pose problème. Étant donné l'exemple ci-dessous, si vous avez un script à lier à jquery dans page.php, vous obtenez cet avis.

$().ready(function () {
    $.ajax({url: "page.php",
        type: 'GET',
        success: function (result) {
        $("#page").html(result);
   }});
 });
Yoweli Kachala
la source
6

Je reçois un tel avertissement dans le cas suivant:

1) fichier1 qui contient <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. La page a des champs de saisie. J'entre une valeur dans le champ de saisie et je clique sur le bouton. Jquery envoie une entrée vers un fichier php externe.

2) le fichier php externe contient également jquery et dans le fichier php externe j'ai également inclus <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. Parce que si je reçois l'avertissement.

Supprimé <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>du fichier php externe et fonctionne sans avertissement.

Si je comprends bien lors du chargement du premier fichier (file1), je charge jquery-1.10.2.jset comme la page ne se recharge pas (elle envoie des données vers un fichier php externe en utilisant jquery $.post), puis jquery-1.10.2.jscontinue d'exister. Il n'est donc plus nécessaire de le charger.

Andris
la source
5

J'ai obtenu cette exception lorsque j'ai défini l'URL dans une requête comme "example.com/files/text.txt". J'ai changé l'URL en " http://example.com/files/text.txt " et cette exception a disparu.

Radren
la source
Mon problème semble également lié à l'URL. J'ai copié un script sur une URL temporaire pour y travailler, et c'est à ce moment que l'erreur est apparue. Pas à partir de l'URL d'origine.
jeffery_the_wind
5

Et j'ai eu cette exception pour inclure un script can.js dans un autre, par exemple,

{{>anotherScript}}
Charles Merriam
la source
Cela semble être la cause principale (chargement de <scripts> supplémentaires et ajouts à la <head> dans le DOM)
Récupération de Nerdaholic le
5

Dans une application MVC, j'ai reçu cet avertissement car j'ouvrais une fenêtre Kendo avec une méthode qui renvoyait un View (), au lieu d'un PartialView (). La vue () tentait de récupérer à nouveau tous les scripts de la page.

Misi
la source
5

Ça m'arrivait en ZF2. J'essayais de charger le contenu Modal mais j'ai oublié de désactiver la mise en page avant.

Donc:

$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;
Ricardo Ruwer
la source
5

Comme @Nycen, j'ai également eu cette erreur en raison d'un lien vers Cloudfare. Le mien était pour le plugin Select2 .

pour le réparer, je viens de retirer

 src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"

et l'erreur a disparu.

Riz Rockwell
la source
5
  1. Dans Chrome, press F12
  2. Outils de développement-> presse F1.
  3. Voir paramètres-> général-> Apparence: "Don't show chrome Data Saver warning"- cochez cette case.
  4. Voir paramètres-> général-> Console: "Log XMLHTTPRequest"- cochez également cette case.

Prendre plaisir

Webgr
la source
4

Dans mon cas, cela était dû au script flexie qui faisait partie de l'application "CDNJS Selections" proposée par Cloudflare .

Selon Cloudflare "Cette application est obsolète en mars 2015". Je l'ai éteint et le message a disparu instantanément.

Vous pouvez accéder aux applications en visitant https://www.cloudflare.com/a/cloudflare-apps/yourdomain.com

NB: ceci est une copie de ma réponse sur ce thread Synchronous XMLHttpRequest warning et <script> (j'ai visité les deux lors de la recherche d'une solution)

Nycen
la source
3

J'ai corrigé cela avec les étapes ci-dessous:

  1. Vérifiez vos scripts CDN et ajoutez-les localement.
  2. Déplacez vos scripts inclus dans la section d'en-tête.
mzonerz
la source
3

Dans mon cas particulier, je rendais un Rails partiel sans render layout: falselequel je restituais la disposition entière, y compris tous les scripts de la <head>balise. L'ajout render layout: falseà l'action du contrôleur a résolu le problème.

dps
la source
3

Pour moi, le problème était que dans une demande OK, je m'attendais à ce que la réponse ajax soit une chaîne HTML bien formatée telle qu'une table, mais dans ce cas, le serveur rencontrait un problème avec la demande, redirigeant vers une page d'erreur, et retournait donc le code HTML de la page d'erreur (qui avait une <scriptbalise quelque part. J'ai console consigné la réponse ajax et c'est alors que j'ai réalisé que ce n'était pas ce que j'attendais, puis j'ai procédé au débogage.

gthuo
la source
2

La question a été soulevée en 2014 et c'est 2019, donc je suppose qu'il est bon de chercher une meilleure option.

Vous pouvez simplement utiliser l' fetchapi en Javascript qui vous offre plus de flexibilité.

par exemple, voir ce code

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Anirudha Gupta
la source
est-ce pur js, aucun plugin requis?
Alok
1
@Alok Oui, veuillez regarder ceci developers.google.com/web/updates/2015/03/introduction-to-fetch
Anirudha Gupta