Fermer

mai 16, 2018

Que diable "Erreur de script" signifie-t-il? –


Cet article a été créé en partenariat avec Sentry.io . Merci de soutenir les partenaires qui rendent SitePoint possible.

Si vous avez déjà travaillé avec l'événement Javascript onerror vous avez probablement rencontré ce qui suit:

Erreur de script. [19659004] "Erreur de script" est ce que les navigateurs envoient au rappel onerror lorsqu'une erreur provient d'un fichier JavaScript provenant d'une origine différente (domaine, port ou protocole différent). C'est douloureux parce que, même s'il y a une erreur, vous ne savez pas quelle est l'erreur ni quel code il est originaire. Et c'est tout le but de window.onerror - obtenir un aperçu des erreurs non interceptées dans votre application.

La Cause: Scripts d'origine croisée

Pour mieux comprendre ce qui se passe, considérons l'exemple suivant HTML document, utilisé de manière hypothétique à partir de http://example.com/test:




  example.com/test   

Voici le contenu de http://another-domain.com/app.js. Il déclare une seule fonction, foo, dont l'invocation lancera toujours une erreur ReferenceError.

 // another-domain.com/app.js
Fonction foo () {
  bar(); // ReferenceError: la barre n'est pas une fonction
}

Lorsque ce document est chargé dans le navigateur et que JavaScript est exécuté, les éléments suivants sont affichés sur la console (consignés via le rappel window.onerror ):

"Erreur de script.", " ", 0, 0, undefined

Ce n'est pas un [JavaScript1945BugBug] - les navigateurs cachent intentionnellement des erreurs provenant de fichiers de script d'origines différentes pour des raisons de sécurité. Il s'agit d'éviter qu'un script ne transmette involontairement des informations potentiellement sensibles à un rappel onerror qu'il ne contrôle pas. Pour cette raison, les navigateurs donnent uniquement un aperçu window.onerror des erreurs provenant du même domaine. Tout ce que nous savons, c'est qu'une erreur est survenue - rien d'autre!

Malgré les bonnes intentions des navigateurs, il y a de très bonnes raisons pour lesquelles vous voulez avoir un aperçu des erreurs lancées par les scripts servis. d'origines différentes:
  1. Votre application Les fichiers JavaScript sont servis à partir d'un nom d'hôte différent (par exemple, static.sentry.io/app.js).
  2. Vous utilisez des bibliothèques provenant d'un CDN communautaire, comme cdnjs ou les bibliothèques hébergées de Google .
  3. Vous travaillez avec une bibliothèque JavaScript commerciale tierce qui n'est servie que par des serveurs externes.

Mais ne vous inquiétez pas! Obtenir un aperçu d'une erreur JavaScript desservie par ces fichiers ne nécessite que quelques modifications simples.

Pour avoir une visibilité sur une exception JavaScript lancée par des scripts provenant d'origines différentes, vous devez faire deux choses. 19659021] 1. Ajoutez un attribut de script crossorigin = "anonyme"

   

Cela indique au navigateur que le fichier cible doit être récupéré "anonymement". Cela signifie qu'aucune information potentiellement identifiante comme les cookies ou les informations d'identification HTTP ne sera transmise par le navigateur au serveur lors de la demande de ce fichier.

 -Control-Allow-Origine:  *

CORS est l'abréviation de Cross Origin Resource Sharing, et c'est un ensemble d'API (principalement des en-têtes HTTP) qui dicte comment les fichiers doivent être téléchargés et servis d'origines différentes.

En paramétrant Access-Control-Allow- Origine: * le serveur indique aux navigateurs que n'importe quelle origine peut récupérer ce fichier. Alternativement, vous pouvez le limiter à une origine connue que vous contrôlez:

 $ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | 
    grep -i "access-control-allow-origine"

Accès-Contrôle-Autoriser-Origine: *

Une fois que ces deux étapes ont été effectuées, toutes les erreurs déclenchées par ce script seront rapportées à window.onerror comme n'importe quel script de même domaine. Ainsi, au lieu de "Script error", l'exemple onerror céderait:

 "ReferenceError: la barre n'est pas définie", "http://another-domain.com/app.js ", 2, 1, [Object Error]

Boom! Vous avez terminé - "Erreur de script" ne vous hantera plus, vous et votre équipe.

An Alternative Solution: try / catch

Parfois, nous ne sommes pas en mesure d'ajuster les en-têtes HTTP des scripts que notre application web consomme. Dans ces situations, il existe une approche alternative: en utilisant try / catch .

Considérez encore l'exemple original, cette fois avec try / catch :

    

Pour la postérité, some-domain.com/app.js ressemble à ceci:

 // another-domain.com/app.js
Fonction foo () {
  bar(); // ReferenceError: la barre n'est pas une fonction
}

L'exécution de l'exemple HTML affichera les deux entrées suivantes dans la console:

 => ReferenceError: la barre n'est pas définie
     à foo (http://another-domain.com/b.js:2:3)
     à http://example.com/test/:15:3

=> "Erreur de script.", "", 0, 0, indéfini

La première déclaration de console - from try / catch - a réussi à obtenir un objet d'erreur complet avec type, message et trace de pile, y compris les noms de fichier et les numéros de ligne. La deuxième déclaration console de window.onerror une fois de plus, ne peut afficher que "Script error".

Maintenant, cela signifie-t-il que vous devez essayer / attraper tout votre code? ? Probablement pas. Si vous pouvez facilement modifier votre HTML et spécifier les en-têtes CORS sur vos CDN, il est préférable de le faire et de s'en tenir à window.onerror .

Mais, si vous ne contrôlez pas ces ressources, utilisez try / catch pour emballer le code tiers est un moyen infaillible (quoique fastidieux) d'obtenir un aperçu des erreurs lancées par les scripts d'origine croisée.

Note: par défaut, raven.js, JavaScript de Sentry SDK instruit soigneusement les méthodes intégrées pour essayer d'envelopper automatiquement votre code dans try / catch blocs. Il le fait pour tenter de capturer les messages d'erreur et empiler les traces de tous vos scripts, quelle que soit l'origine à partir de laquelle ils sont servis. Il est toujours recommandé de définir les attributs et les en-têtes CORS si possible.

Bien sûr, il existe de nombreux outils commerciaux et open-source qui assurent la lourde tâche de générer des rapports sur le client. (Psst: vous pourriez vouloir essayer Sentry pour déboguer JavaScript.)

C'est tout! Heureux erreur de surveillance .




Source link