J’obtiens cette erreur JavaScript sur ma console :
Erreur de syntaxe non détectée : Unxpected token ILLEGAL
Voici mon code :
var foo = 'bar';
Comme vous pouvez le constater, c'est très simple. Comment cela pourrait-il causer une erreur de syntaxe ?
Lorsque le code est analysé par l'interpréteur JavaScript, il est divisé en morceaux appelés "tokens". Lorsqu'un jeton ne peut pas être classé dans l'un des [quatre types de jetons de base][13], il est étiqueté "ILLEGAL" ; sur la plupart des implémentations, et cette erreur est déclenchée.
La même erreur est levée si, par exemple, vous essayez d'exécuter un fichier js avec un caractère @
, une accolade mal placée, un crochet, des guillemets intelligents, des guillemets simples mal fermés (par exemple this.run('dev1)
) et ainsi de suite.
De nombreuses situations différentes peuvent provoquer cette erreur. Mais si vous n'avez pas d'erreur de syntaxe ou de caractère illégal évident, elle peut être causée par un caractère illégal invisible. C'est le sujet de cette réponse.
Il existe un caractère invisible dans le code, juste après le point-virgule. Il s'agit du caractère [Unicode U+200B
Espace de largeur nulle][1] (alias ZWSP
, entité HTML
). Ce caractère est connu pour provoquer l'erreur de syntaxe JavaScript Unexpected token ILLEGAL
.
Je ne peux pas le dire avec certitude, mais je parie sur [jsfiddle][2]. Si vous collez du code à partir de là, il est très probable qu'il contienne un ou plusieurs caractères U+200B
. Il semble que l'outil utilise ce caractère pour contrôler la mise en forme des mots dans les longues chaînes de caractères.
MISE À JOUR 2013-01-07
Après la dernière mise à jour de jsfiddle, [le caractère est maintenant affiché sous forme de point rouge][jsfiddle-demo] comme le fait codepen. Apparemment, il'n'insère plus non plus les caractères
U+200B
tout seul, donc ce problème devrait être moins fréquent à partir de maintenant. MISE À JOUR 2015-03-17Vagrant semble parfois causer ce problème également, en raison d'un bug dans VirtualBox. La solution, selon cet article de blog est de définir
sendfile off;
dans votre configuration nginx, ouEnableSendfile Off
si vous utilisez Apache. Il a également été signalé que le code collé à partir des outils de développement de Chrome peut inclure ce caractère, mais je n'ai pas pu le reproduire avec la version actuelle (22.0.1229.79 sur OSX).Comment puis-je le repérer ?
Le caractère est invisible, comment savoir s'il est là ? Vous pouvez demander à votre éditeur d'afficher les caractères invisibles. La plupart des éditeurs de texte disposent de cette fonctionnalité. Vim, par exemple, les affiche par défaut, et le
ZWSP
s'affiche comme<u200b>
. Vous pouvez également le déboguer en ligne : jsbin affiche le caractère sous la forme d'un point rouge dans ses volets de code (mais semble le supprimer après avoir enregistré et rechargé la page). CodePen.io l'affiche également sous forme de point, et le conserve même après l'enregistrement.Problèmes connexes
Ce caractère n'est pas quelque chose de mauvais, il peut même être très utile. Cet exemple sur Wikipedia montre comment il peut être utilisé pour contrôler l'endroit où une longue chaîne de caractères doit passer à la ligne suivante. Cependant, si vous n’avez pas conscience de la présence de ce caractère dans votre balisage, il peut devenir un problème. Si vous l'avez à l'intérieur d'une chaîne de caractères (par exemple, le
nodeValue
d'un élément DOM qui n'a pas de contenu visible), vous pourriez vous attendre à ce que cette chaîne soit vide, alors qu'en fait elle ne l'est pas (même après avoir appliquéString.trim
).ZWSP
peut également provoquer l'affichage d'un espace blanc supplémentaire sur une page HTML, par exemple lorsqu'il se trouve entre deux éléments<div>
(comme vu sur cette question). Ce cas n'est même pas reproductible sur jsfiddle, puisque le caractère y est ignoré. Un autre problème potentiel : si l'encodage de la page web n'est pas reconnu comme UTF-8, le caractère peut être affiché (commeâ€'
en latin1, par exemple). SiZWSP
est présent dans du code CSS (code en ligne ou feuille de style externe), les styles peuvent aussi ne pas être analysés correctement, et certains styles ne sont pas appliqués (comme on le voit sur cette question).La spécification ECMAScript
Je n'ai trouvé aucune mention de ce caractère spécifique dans la spécification ECMAScript (versions 3 et 5.1). La version actuelle mentionne des caractères similaires (
U+200C
etU+200D
) dans la Section 7.1, qui indique qu'ils doivent être traités comme desIdentifierPart
s lorsque "en dehors des commentaires, des littéraux de chaîne et des littéraux d'expression régulière" ;. Ces caractères peuvent, par exemple, faire partie d'un nom de variable (etvar x\u200c;
fonctionne effectivement). La section 7.2 énumère les caractères d'espace blanc valides (tels que tabulation, espace, espace sans coupure, etc.), et mentionne vaguement que tout autre " séparateur d'espace " Unicode (catégorie " Z ") devrait être traité comme un espace blanc. Je ne suis probablement pas la meilleure personne pour discuter des spécifications à cet égard, mais il me semble queU+200B
devrait être considéré comme un espace blanc selon cela, alors qu'en fait les implémentations (au moins Chrome et Firefox) semblent les traiter comme un token inattendu (ou une partie d'un token), causant l'erreur de syntaxe.
pourquoi cherchez-vous ce problème dans votre code ? Même, si c’est un copié-collé.
Si vous pouvez voir ce qui se passe exactement après l'enregistrement du fichier dans le dossier synchronisé, vous verrez quelque chose comme *****
à la fin du fichier. Ce n'est pas du tout lié à votre code.
Solution.
Si vous utilisez nginx
dans une boîte vagrant - ajoutez à la configuration du serveur :
sendfile off;
Si vous utilisez apache
dans la boîte vagrant - ajoutez à la configuration du serveur :
EnableSendfile Off;
Source du problème : [Bug de VirtualBox][1]
[1] : https://github.com/mitchellh/vagrant/issues/351#issuecomment-1339640
Cela peut également se produire si vous copiez le code d'un autre document (comme un PDF) dans votre console et que vous essayez de l'exécuter.
J'ai essayé d'exécuter un exemple de code tiré d'un livre sur le Javascript que je suis en train de lire et j'ai été surpris qu'il ne s'exécute pas dans la console.
Apparemment, la copie d'un PDF introduit des caractères inattendus, illégaux et invisibles dans le code.