web-dev-qa-db-fra.com

JavaScript console.log provoque l'erreur: "XMLHttpRequest synchrone sur le thread principal est obsolète ..."

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

Cependant, dans de nombreux endroits où j'ajoute un console.log dans mon fichier main.js, le message d'erreur suivant s'affiche à la place de mes adorables petits messages manuscrits à moi-même: 

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.log puis-je ajouter à mon code d'utilisation qui ne causera pas cette erreur? 

Est-ce que je "fais le mal"? 

337
Nathan Basanese

Cela m'est arrivé alors que j'étais paresseux et que 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, du moins dans mon cas, que si vous renvoyez un contenu HTML de la sorte via xhr, vous obligerez jQuery à 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 feriez mieux de consulter un cadre de liaison quelconque et de simplement renvoyer un objet JSON, ou en fonction de votre backend et de vos modèles, vous pourriez changer le mode de chargement des scripts. 

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

Exemple

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

http://jsfiddle.net/49tkL0qd/

254
kroolk

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 :

XMLHttpRequest synchrone en dehors des travailleurs est en train de.. être retiré de la plate-forme Web car il a des effets néfastes sur l'expérience de l'utilisateur final. (Il s’agit d’un long processus qui prend plusieurs Années.) Les développeurs ne doivent pas transmettre false pour l’argument async. L'environnement global JavaScript est un environnement de document. Agents utilisateurs sont fortement encouragés à avertir de cette utilisation dans les outils de développement et peut expérimenter le lancement d'une exception InvalidAccessError lorsque ça arrive.

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

67
PedanticDan

Je faisais également face au même problème, mais j'ai pu le résoudre en mettant async: true. Je sais que c'est vrai par défaut 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 }),
});
56
Irfan Ashraf

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

28
Charlie

Il est parfois nécessaire d’ajax charger un script mais de retarder document prêt jusqu’à ce que le script soit chargé.

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

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 de script réel est asynchrone (no error), mais l’effet est synchrone si le reste de votre JavaScript est exécuté après document prêt.

Cette fonctionnalité avancée serait généralement utilisée par le script dynamique des chargeurs souhaitant charger du code JavaScript supplémentaire, tel que des plugins 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 méthode jQuery.holdReady() 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 pour des durées prolongées.

Solution: Réécrivez la page de manière à ce que tous les gestionnaires prêts pour jQuery ne soient pas retardés. Cela peut être accompli, par exemple, en chargeant tardivement uniquement le code qui nécessite le délai d’exécution en toute sécurité. 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 cet avertissement.

15
Dem Pilafian

Pour éviter cet avertissement, n'utilisez pas:

async: false

dans n'importe lequel de vos appels $ .ajax (). C'est la seule fonctionnalité de XMLHttpRequest qui est déconseillée.

La valeur par défaut est 

async: true

jQuery a déconseillé d'utiliser XMLHTTPRequest synchrone

13
Sonu K

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

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

  1. Utiliser le navigateur Chrome> Appuyez sur F12 pour créer DevTools
  2. Ouvrez le menu tiroir (dans Chrome 3 points verticaux en haut à droite)
  3. Sous Console > vérifier Journal XMLHttpRequests option
  4. Rechargez la page qui vous donnait l'erreur et observez ce qui se passe à chaque requête 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 ni nécessaires ni nécessaires. La désactivation du plug-in non autorisé a supprimé l'avertissement du journal. À partir de ce moment, 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 - ceci est trop spécifique pour une réponse ici) ou contacter un développeur de plug-in tiers pour le résoudre.

J'espère que ça aide quelqu'un.

11
dev101

J'ai regardé les réponses toutes impressionnantes. Je pense qu'il devrait fournir le code qui lui donne un problème. Si vous avez un script à associer à jQuery dans page.php, voici l’avis. 

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

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 cliquez sur le bouton. Jquery envoie une entrée à 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. 

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

Si je comprends bien lors du chargement du premier fichier (fichier1), je charge jquery-1.10.2.js et comme la page ne se recharge pas (elle envoie des données à un fichier php externe en utilisant jquery $.post), alors jquery-1.10.2.js continue d'exister. Il n'est donc pas nécessaire de le charger à nouveau.

5
Andris
  1. Dans Chrome, press F12
  2. Outils de développement-> appuyez sur F1.
  3. Voir Paramètres-> Général-> Aspect: "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

4
Webgr

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

4
Misi

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

{{>anotherScript}}
4
Charles Merriam

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

4
Radren

Comme @Nycen, cette erreur est également due à un lien vers Cloudfare. Le mien était pour le Select2 plugin.

pour résoudre ce problème, je viens de retirer

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

et l'erreur est partie.

4
Rockwell Rice

Cela m'arrivait dans ZF2… .. J'essayais de charger le contenu Modal mais j'avais oublié de désactiver la mise en page auparavant.

Alors:

$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;
4
Ricardo Ruwer

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 fil de discussion Synchronous XMLHttpRequest warning et <script> (J'ai visité les deux lors de la recherche d'une solution)

3
Nycen

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 en-tête.
2
mzonerz

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 balise <script quelque part. Je consignai la réponse ajax et c'est alors que je réalisai que ce n'était pas ce à quoi je m'attendais, puis je procédai au débogage.

2
gthuo

Dans mon cas particulier, je rendais une partie de Rails sans render layout: false, ce qui revenait à rendre toute la présentation, y compris tous les scripts de la balise <head>. L'ajout de render layout: false à l'action du contrôleur a résolu le problème.

2
dps

La question posée en 2014 et en 2019, je suppose qu'il est bon de rechercher une meilleure option.

Vous pouvez simplement utiliser fetch api en Javascript pour vous offrir plus de flexibilité.

par exemple, voir ce code

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
0
Anirudha Gupta