«Erreur de script» cryptique. signalé en Javascript dans Chrome et Firefox

199

J'ai un script qui détecte les erreurs Javascript sur mon site Web et les envoie à mon backend pour rapport. Il signale la première erreur rencontrée, le numéro de ligne supposé et l'heure.

EDIT pour inclure doctype:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">

...

<script type="text/javascript">
//<![CDATA[
// for debugging javascript!
(function(window){
    window.onerror = function(msg, url, ln) {
        //transform errors
        if (typeof(msg) === 'object' && msg.srcElement && msg.target) {
            if(msg.srcElement == '[object HTMLScriptElement]' && msg.target == '[object HTMLScriptElement]'){
                msg = 'Error loading script';
            }else{
                msg = 'Event Error - target:' + msg.target + ' srcElement:' + msg.srcElement;
            }
        }

        msg = msg.toString();

        //ignore errors
        if(msg.indexOf("Location.toString") > -1){
            return;
        }
        if(msg.indexOf("Error loading script") > -1){
            return;
        }

        //report errors
        window.onerror = function(){};
        (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url || document.location.toString().replace(/#.*$/, "")) + "&ln=" + parseInt(ln || 0) + "&r=" + (+new Date());
    };
})(window);
//]]>
</script>

À cause de ce script, je suis parfaitement au courant des erreurs javascript qui se produisent sur mon site. L'un des plus grands délinquants est «Erreur de script». sur la ligne 0. dans Chrome 10+ et Firefox 3+. Cette erreur n'existe pas (ou peut être appelée quelque chose d'autre?) Dans Internet Explorer.

Correction (23/05/2013): Cette erreur "Erreur de script, ligne 0" apparaît maintenant dans IE7 et éventuellement dans d'autres versions d'IE. Peut-être le résultat d'un correctif de sécurité IE récent, car ce comportement n'existait pas auparavant.

Quelqu'un a-t-il une idée de ce que signifie cette erreur ou de sa cause? Cela se produit sur environ 0,25% de mes pageloads globaux et représente la moitié des erreurs signalées.

Mike Sherov
la source
Quel est votre doctype? Si vous ne déclarez pas un doctype XHTML, vous n'avez pas besoin de CDATA, ce qui pourrait être la raison des erreurs de script.
James
J'apprécie l'aide ... Ajout du doctype: XHTML. De plus, cependant, cela ne se produit que sur 0,25% des pageloads ... Je pense que c'est quelque chose de plus exotique.
Mike Sherov
3
@jayp: Je viens de mentionner. Le doctype XHTML est toujours un analyseur HTML. Vous devez envoyer du contenu application/xhtml+xmlpour l'exécuter dans l'analyseur XHTML (comme le dit la spécification XHTML). Il y a beaucoup de contenu qui prétend être XHTML, mais envoie un doctype HTML normal. En raison de la façon incorrecte dont les créateurs de contenu utilisent XHTML, les navigateurs ont décidé de n'utiliser que l'analyseur XML application/xhtml+xml(c'est un analyseur vraiment strict). Les hixie.ch/advocacy/xhtml et webdevout.net/articles/beware-of-xhtml expliquent pourquoi ne pas utiliser l'analyseur HTML avec XHTML.
Konrad Borowski
11
Soupir ... pour l'amour de dieu, quiconque lit ceci, veuillez expliquer à vos messages d'erreur ce qui s'est mal passé! En vous épargnant 30 secondes d'efforts pour l'écrire, vous perdez les années-hommes dans le monde!
Roman Starkov
1
Vous ignorez les erreurs de chargement des scripts d'erreur. Pourquoi? Sont-ils sûrs d'ignorer?
rampr

Réponses:

261

"L'erreur de script". se produit dans Firefox, Safari et Chrome lorsqu'une exception viole la politique de même origine du navigateur - c'est-à-dire lorsque l'erreur se produit dans un script hébergé sur un domaine autre que le domaine de la page actuelle.

Ce comportement est intentionnel, pour empêcher les scripts de divulguer des informations vers des domaines externes. Pour un exemple de pourquoi cela est nécessaire, imaginez une visite accidentelle evilsite.com, qui sert une page avec <script src="yourbank.com/index.html">. (oui, nous pointons cette balise de script sur html, pas sur JS). Cela entraînera une erreur de script, mais l'erreur est intéressante car elle peut nous dire si vous êtes connecté ou non. Si vous êtes connecté, l'erreur pourrait être 'Welcome Fred...' is undefined, alors que si vous ne l'êtes pas, elle pourrait l'être 'Please Login ...' is undefined. Quelque chose dans ce sens.

Si evilsite.com fait cela pour les 20 plus grandes institutions bancaires, elles auraient une assez bonne idée des sites bancaires que vous visitez et pourraient fournir une page de phishing beaucoup plus ciblée. (Ceci n'est qu'un exemple, bien sûr. Mais il illustre pourquoi les navigateurs ne devraient pas permettre à des données de traverser les limites du domaine.)

J'ai testé cela dans les dernières versions de Safari, Chrome et Firefox - ils le font tous. IE9 ne le fait pas - il traite les exceptions d'origine x de la même manière que celles d'origine identique. (Et Opera ne prend pas en charge onerror.)

De la bouche du cheval: source WebKit qui vérifie l'origine lors du passage d'exceptions à onerror (). Et la source Firefox qui vérifie .

MISE À JOUR (21/10/11) : Le bogue Firefox qui suit ce problème comprend un lien vers le billet de blog qui a inspiré ce comportement.

MISE À JOUR (02/12/14) : Vous pouvez désormais activer le rapport d'erreurs interdomaines complet sur certains navigateurs en spécifiant un crossoriginattribut sur les balises de script et en demandant au serveur d'envoyer les en-têtes de réponse HTTP CORS appropriés .

broofa
la source
3
Merci pour cela. J'aimerais un éclaircissement. Je vois des messages d'erreur détaillés des scripts que j'inclus sur ma page tout le temps. Par exemple, si j'inclus jQuery à partir du cdn de google et que je l'utilise pour manipuler un élément inexistant sur ma page, j'obtiens une erreur qui pointe vers le CDN de google. Voulez-vous dire que "Erreur de script." qui se passe parce que le script distant lève l'exception?
Mike Sherov
150
Vous auriez pensé que quelqu'un aurait eu le sens de dire "Un script distant a jeté une erreur qui a été cachée en raison de la même politique d'origine", au lieu de vous laisser vous demander ce qui ne va pas, hein? ...
Roman Starkov
3
@broofa Cela signifie-t-il que je serai meilleur sauf si j'héberge jquery sur mon domaine au lieu d'utiliser le CDN de Google?
Paul Biggar
6
Petite mise à jour. Cela se produit également localement lorsqu'une page est chargée via file: // et que le script est exécuté via eval (). Cas d'utilisation mineur mais quand même :)
Willem Mulder
6
Après quelques recherches, j'ai remarqué qu'un événement Script Error.se produit également si l'utilisateur a installé une extension Safari (probablement la même chose pour les plug-ins Firefox) qui injecte du code JavaScript avec des erreurs
Alex Hoppen
49

Une mise à jour pour ceux qui se heurteront à cette question à l'avenir: broofa a raison avec la réponse et il n'y a pas de solution pour cela.

De toute évidence, d'autres sont tombés sur cette limitation et certains bogues demandant un correctif ont été déposés pour Firefox: bogue 69301 et pour WebKit: bogue 70574.

La bonne nouvelle est que le bug a été résolu pour Firefox avec la sortie de Firefox 13. Voici comment vous l'utilisez:

<script src="http://somremotesite.example/script.js" crossorigin>

crossoriginest équivalent crossorigin=anonymouset indique au navigateur d' effectuer une extraction CORS du script sans envoyer d'informations d'identification.

Vous devez vous assurer que le script est envoyé avec une Access-Control-Allow-Originvaleur d'en-tête HTTP qui correspond au domaine demandeur, par exemple,

Access-Control-Allow-Origin: http://myhomesite.example
Access-Control-Allow-Origin: *

sinon, le navigateur annulera le chargement du script .

Pour Apache:

Header set Access-Control-Allow-Origin "*"

(Et voir des exemples CORS pour d' autres serveurs Web .)

Si vous envoyez des scripts en PHP:

header('Access-Control-Allow-Origin', 'http://myhomesite.example');

J'ai testé cela et cela fonctionne comme prévu. toutes les erreurs du script.js seront détectées par le window.onerrorgestionnaire avec les détails du message, du fichier et de la ligne.

Le bogue WebKit n'a pas encore été corrigé, mais un correctif a été proposé (et utilise la même solution). Espérons que le correctif sera bientôt publié.

Plus d'informations sur CORS ici: http://enable-cors.org/

adig
la source
2
Bon résumé: blog.errorception.com/2012/12//
sam
1
Re webkit. Si vous voulez dire celui-ci, il semble qu'il soit résolu maintenant: bugs.webkit.org/show_bug.cgi?id=70574
UpTheCreek
3
Disons que nous voulons surveiller les erreurs JS dans mysite.com/index.php, qui inclut un fichier JS d'une partie externe (par exemple, le serveur d'un fournisseur d'API apiprovider.com/api.js); dans ce cas, nous n'avons pas accès à ce serveur, nous ne pouvons donc pas ajouter l'en-tête "Access-Control-Allow-Origin". Existe-t-il un moyen d'obtenir des messages d'erreur provenant d'api.js?
Eugenio
23

Celui-ci a pris beaucoup de temps à comprendre.

Nous avons fait un tas de choses pour essayer de le résoudre, y compris en faisant des choses comme le vidage du corps du document ENTIER sur nos serveurs via Ajax pour essayer de le comprendre.

Je ne sais toujours pas ce qui cause une "erreur de script". (avec la période BTW, c'est comme ça que ça se voit dans notre enregistreur Ajax) dans Firefox, mais dans Chrome, nous avons pu le réduire à ...

Roulement de tambour...

La fonctionnalité de traduction automatique de Google Chrome.

Beaucoup de personnes anglophones ne connaissent probablement même pas cette fonctionnalité, mais pour la tester, je suppose que vous visitez un site non anglais en utilisant Chrome. Ou mieux encore, si vous fouillez dans les options de Chrome, il y a un endroit pour changer la langue du navigateur. Changez-le en quelque chose de non anglais, redémarrez le navigateur et visitez un site anglais.

La barre en haut devrait vous demander si vous souhaitez que Chrome traduise la page pour vous.

Dans notre cas de toute façon, le traducteur était à l'origine du problème car il injecte une balise de script dans le corps de votre document et (devinant ici) utilise une sorte de système basé sur JS pour envoyer le contenu aux serveurs de Google et les amener à le traduire.

Même si l'erreur dans la console était un élément sans référence, le message envoyé à window.onerror était «Erreur de script».

Quoi qu'il en soit, il existe un remède.

http://googlewebmastercentral.blogspot.com/2007/12/answering-more-popular-picks-meta-tags.html

<meta name="google" content="notranslate"/>

Cela fera 2 choses (à notre connaissance, peut-être plus?):

a) Désactivez la barre de traduction pour qu'elle apparaisse dans Chrome.

b) Désactivez la traduction de la page via translate.google.com.

Dans notre situation de toute façon, cela a résolu UNE TONNE de ces «erreurs de script». les problèmes que nous rencontrions.

Excusez les fautes d'orthographe dans cet article, je suis toujours en mode non anglais dans Chrome pour écrire ceci, et le correcteur orthographique n'est pas réglé sur l'anglais;) Il est temps de revenir en arrière.

Prendre plaisir!

anonyme-un
la source
4
La raison directe est probablement que le script du traducteur a été exécuté à partir d'un domaine différent de la page Web et onerror(au moins dans Firefox) dit simplement "Erreur de script" dans un tel cas.
Tgr
10

En raison du faible%, vous pouvez supposer qu'ils ne sont pas des utilisateurs normaux. Probablement des utilisateurs avec des scripts utilisateur, des bookmarklets ou même peut-être simplement en train de jouer avec la console sur votre site Web. Avoir tout le code HTML d'une page là où cela se produit pourrait aider à tester cette théorie. Ainsi que l'erreur complète. Il devrait vous donner une URL, est-ce toujours la même chose? La ligne est-elle vraiment 0 ou simplement indéfinie?

Je ne pense pas que la définition de valeurs par défaut en vous sur une erreur soit une bonne idée et le 0 vient probablement du parseInt(ln || 0)moment où l'erreur n'est pas vraiment sur la page (voir les exemples ci-dessus).

Ajouter un if pour voir si la ligne est connue soit dans le JavaScript pour ignorer ces erreurs (car elles ne proviennent probablement pas de votre propre code) ou dans le code côté serveur pour s'en occuper séparément serait, imo, mieux .

=== EDIT === Allez à: http://www.xavierm02.net/AZE/ Installez le fichier user.js (je l'ai fait sur Chrome mais cela devrait aussi fonctionner sur Firefox). Ouvrez ensuite la page html sur le même navigateur. Il vous montrera l'erreur (je n'ai changé que l'instal de rapport au serveur, il l'écrit sur la page). Avec 0 comme numéro de ligne.

xavierm02
la source
L'URL est répartie également entre les pages de mon site. J'imagine des bookmarklets ou même des extensions ou des thèmes, étant donné que c'est FF et chrome. Cependant, j'aimerais pouvoir reproduire ce message d'erreur exactement avant de l'ignorer en toute sécurité.
Mike Sherov
Remplacez votre ligne par (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url) + "&ln=" + parseInt(ln) + "&r=" + (+new Date());et vous ne verrez probablement pas d'URL (car c'est une extension ou quelque chose de local pour que le navigateur ne vous montre pas) et pas de numéro de ligne.
xavierm02
Et btw, vous devriez plutôt obtenir l'horodatage avec votre serveur plutôt qu'avec JS (et peut-être même simplement obtenir la version, au lieu de l'horodatage).
xavierm02
1
En fait, JS devrait simplement envoyer les données brutes et PHP devrait prendre soin d'ignorer les erreurs de chargement, etc.
xavierm02
Je fais un peu de traitement du côté JS parce que je veux seulement signaler la PREMIÈRE erreur pertinente, donc je réattribue la fonction onerror à rien après qu'une erreur réelle se soit produite. .
Mike Sherov
3

J'ai eu un problème similaire: mes scripts sont servis par un sous-domaine et tombent sous la même restriction d'origine. Cependant, j'ai résolu cela en:

1) en ajoutant chaque balise de script comme ceci:

<script type="text/javascript" src="http://subdomain.mydomain.tld" crossorigin="*.mydomain.tld" />

2) modifier l'apache httpd.conf en ajoutant ce qui suit à l'intérieur de chaque vhost (vous devez activer mod_headers):

<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*.mydomain.tld"
</IfModule>

J'espère que cela t'aides ...

ÉDITER

Sur un de mes serveurs, je n'ai pas pu rendre cela fonctionnel, sauf en remplaçant

*.mydomain.tld

par

*

Soyez conscient des failles de l'autorisation potentielle * de phishing d'informations étendues. La documentation sur CORS, même origine, img et polices, cdn est disponible, mais très peu de détails sur l'origine des balises de script sont disponibles.

spoutnik
la source
1
"* .mydomain.tld" n'est pas une valeur valide pour l'attribut crossorigin developer.mozilla.org/en-US/docs/Web/HTML/…
icenac
1

Dans Chrome, j'obtiens également une "erreur de script" (à la ligne 0) lors du chargement du HTML et du Javascript à partir de file://. Cela ne se produit pas dans Firefox. Probablement une protection trop zélée de la même origine pour Chrome.

Tout va bien lors du chargement du même HTML et Javascript sur HTTP.

Myrne Stol
la source
1

Que diriez-vous du ci-dessous. L'erreur de script n'est pas disponible via JavaScript, il vous suffit donc d'isoler ce cas particulier et de le gérer du mieux que vous le pouvez.

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        alert(msg, url, lineNo, columnNo, error);
    }
  return false;
};
Ronnie Royston
la source
comment enregistrez-vous cela sur le karma?
CommonSenseCode
Êtes-vous en train de dire que la console du navigateur contient les détails, mais pas l'erreur?
Michael Freidgeim
0

Chrome et Firefox sur iOS sont tous deux basés sur Safari Webview mais insèrent un tas de scripts personnalisés dans chaque page chargée. Si, dans l'un de ces scripts, quelque chose ne va pas, il est également signalé Script error on line 0. (Les scripts insérés par le navigateur comptent également comme origine croisée)

Comme je l'ai retrouvé et documenté dans cet autre thread SO, Chrome et Firefox sur iOS ont des problèmes dans leurs scripts personnalisés qui gèrent correctement les éléments SVG. Donc, en plus de toutes les autres réponses de ce fil: si vous utilisez des éléments SVG et des <a>balises dans les <svg>balises de votre page, cela entraînera Script errorsun signalement dans iOS Chrome et iOS Firefox.

Laszlo Korte
la source
-1

Je vais vous dire ce qui l'a corrigé pour moi sur Safari (WebKit): Si je mets la routine de rappel JS sur la page , alors j'obtiens des informations complètes. Si je l'inclus dans un fichier .js via une balise, j'obtiens simplement l'erreur "Script error" (sans linumber, etc.).

Peut-être que cela est lié à ce que Broofa a dit.

Anwyay, alors maintenant j'ai un petit rappel dans la page, puis le reste du fichier en dehors de la page.

kbern
la source
-2

J'ai fait un peu de recherche et il semble qu'une "erreur de script" signifie qu'il a eu du mal à charger un fichier qu'on lui a demandé de rechercher. Cela peut être un problème de mise en cache côté client ou un problème de serveur dû à une surcharge.

C'est probablement dû à quelque chose comme ça où le script lui-même est le fichier qu'il ne peut pas charger, d'où l'erreur survenue à la ligne 0.

<script type="text/javascript" src="somescript.js"></script>
Nick Brunt
la source
Bonne pensée, mais nous ignorons explicitement quand un script ne se charge pas. Nous avons détecté cette erreur spécifiquement et l'ignorons.
Mike Sherov
1
Comment avez-vous détecté lorsqu'un script ne se charge pas? Je me souviens avoir eu des problèmes avec ça à un moment donné. script.onerrorn'a pas été renvoyé pour les scripts manquants dans certains navigateurs.
Charlie Kilian
"Erreur source." (little-e) apparaît dans les sources webkit et FF. Voir ma réponse ci-dessus. fwiw.
broofa
-3

J'ai connu

Erreur de script. ligne 0

les erreurs signalées pendant un certain temps à notre serveur lorsque l'erreur s'est produite dans les navigateurs des clients. Hier pour la première fois (après avoir introduit "use strict";dans notre javascript) j'ai pu reproduire ce problème dans Safari et Chrome sur Windows 7. Après avoir jonché notre code d'instructions alert (), j'ai retracé cette erreur jusqu'à l'utilisation d'une variable non définie! par exemple, xx = 123;xx n'est pas défini avec une varinstruction.

Safari l'a signalé comme

ReferenceError: le mode strict interdit la création implicite de la propriété globale 'xx'

dans Web Inspector, mais la fonction window.onerror détectait

Erreur de script. ligne 0

Zombie errant
la source
-11

Grepping le code source de Firefox révèle qu'il n'y a pas "Script Error.". Ainsi, il est très probable qu'un script sur votre site génère une erreur non capturée comme celle-ci:

throw new Error('Script Error.');

Cette déclaration n'est probablement atteinte que dans Firefox et Chrome.

Je ne sais pas pourquoi il n'y a pas de numéro de ligne. Peut-être un eval()problème?

user123444555621
la source
1
J'ai essayé de lancer cela exactement comme vous l'avez recommandé. Il ne signale pas «Erreur de script». Il signale «exception levée non interceptée: erreur de script». Bonne pensée cependant.
Mike Sherov
Il peut également s'agir de l'une des extensions installées par l'utilisateur à l'origine de l'erreur.
Charlie Kilian
1
En aucune façon. Vous verrez «Erreur de script» partout sur le Web si vous regardez dans les bons écrans.
Amalgovinus
2
Euh non. Il s'agit en fait d'une "erreur de script". avec un petit "e". C'est pourquoi je ne l'ai pas trouvé dans le code source.
user123444555621