Aucune cause visible pour «jeton inattendu ILLEGAL»

270

Je reçois cette erreur JavaScript sur ma console:

SyntaxError non capturée: jeton inattendu ILLEGAL

Voici mon code:

var foo = 'bar';​

C'est super simple, comme vous pouvez le voir. Comment cela pourrait-il provoquer une erreur de syntaxe?

bfavaretto
la source
9
Pour les futurs lecteurs: si vous avez rencontré cette erreur lors de l'utilisation de Vagrant - cette réponse peut également être utile: stackoverflow.com/questions/9479117/…
OZ_
Si vous rencontrez ce problème dans WordPress, mettez les scripts en file d'attente à partir de functions.php. J'avais un modèle spécifique où j'appelais le JS directement à partir du modèle. Le passage à une mise en file d'attente conditionnelle dans wp_head ou wp_footer a résolu ce problème.
Alpesh Shah
7
Note du modérateur: J'ai supprimé un tas de réponses ici qui ne répondent pas réellement à la question. Ce n'est pas, je le répète pas , un endroit à la liste toutes les choses possibles que vous pouvez faire en JavaScript qui entraînera cette erreur. La question a une circonstance très spécifique qui n'implique aucun de ces scénarios, et tous ces exemples ne répondent tout simplement pas à la question.
animuson
3
Wow, la police SO a eu une journée de terrain avec cette question. Heureusement, certaines des informations pertinentes sont toujours visibles dans les réponses supprimées.
cdonner le

Réponses:

493

L'erreur

Lorsque le code est analysé par l'interpréteur JavaScript, il est divisé en morceaux appelés "jetons". Lorsqu'un jeton ne peut pas être classé dans l'un des quatre types de jetons de base , il est étiqueté "ILLEGAL" sur la plupart des implémentations et cette erreur est levée.

La même erreur se produit si, par exemple, vous essayez d'exécuter un fichier js avec un @caractère escroc , une accolade frisée 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 évidente ou de caractère illégal, cela peut être dû à un caractère illégal invisible . C'est de cela qu'il s'agit.

Mais je ne vois rien d'illégal!

Il y a un caractère invisible dans le code, juste après le point-virgule. C'est le caractère d' U+200Bespace Unicode Zero-width (aka ZWSP, entité HTML ​). Ce caractère est connu pour provoquer l' Unexpected token ILLEGALerreur de syntaxe JavaScript.

Et d'où vient-il?

Je ne peux pas le dire avec certitude, mais mon pari est sur jsfiddle . Si vous collez du code à partir de là, il est très probable qu'il contienne un ou plusieurs U+200Bcaractères. Il semble que l'outil utilise ce caractère pour contrôler l'habillage des mots sur les longues chaînes.

MISE À JOUR 2013-01-07

Après la dernière mise à jour de jsfiddle , il affiche maintenant le personnage comme un point rouge comme le fait codepen. Apparemment , il n'insère plus de U+200Bcaractères seul, donc ce problème devrait être moins fréquent à partir de maintenant.

MISE À JOUR 2015-03-17

Vagrant semble parfois causer ce problème, en raison d'un bogue dans VirtualBox . La solution, selon ce billet de blog, est de définir sendfile off;dans votre configuration nginx, ou EnableSendfile Offsi vous utilisez Apache.

Il a également été signalé que le code collé à partir des outils de développement 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 le repérer?

Le personnage est invisible, comment savons-nous qu'il est là? Vous pouvez demander à votre éditeur d'afficher des caractères invisibles. La plupart des éditeurs de texte ont cette fonctionnalité. Vim, par exemple, les affiche par défaut, et les ZWSPaffiche comme <u200b>. Vous pouvez également le déboguer en ligne: jsbin affiche le caractère sous la forme d'un point rouge sur 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 liés

Ce personnage n'est pas quelque chose de mauvais, il peut en fait être très utile. Cet exemple sur Wikipedia montre comment il peut être utilisé pour contrôler où une longue chaîne doit être placée à la ligne suivante. Cependant, si vous n'êtes pas au courant de la présence du personnage sur votre balisage, cela peut devenir un problème. Si vous l'avez à l'intérieur d'une chaîne (par exemple, nodeValued'un élément DOM qui n'a pas de contenu visible), vous pouvez vous attendre à ce qu'une telle chaîne soit vide, alors qu'en fait ce n'est pas le cas (même après application String.trim).

ZWSPpeut également entraîner l'affichage d'un espace supplémentaire sur une page HTML, par exemple lorsqu'il se trouve entre deux <div>éléments (comme on le voit sur cette question ). Ce cas n'est même pas reproductible sur jsfiddle, car le personnage y est ignoré.

Autre problème potentiel: si l'encodage de la page Web n'est pas reconnu comme UTF-8, le caractère peut en fait s'afficher (comme ​en latin1, par exemple).

Si ZWSPest présent sur le code CSS (code en ligne ou une feuille de style externe), les styles ne peuvent pas non plus être analysés correctement, donc 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+200Cet U+200D) dans la section 7.1 , qui indique qu'ils doivent être traités comme des IdentifierParts "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 (et var x\u200c;fonctionnent en effet).

La section 7.2 répertorie les caractères d'espace blanc valides (tels que tabulation, espace, espace insécable, etc.) et mentionne vaguement que tout autre «séparateur d'espace» Unicode (catégorie «Zs») doit ê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 que cela U+200Bdevrait être considéré comme un espace blanc en fonction de cela, alors qu'en fait les implémentations (au moins Chrome et Firefox) semblent les traiter comme un inattendu jeton (ou une partie), provoquant l'erreur de syntaxe.

bfavaretto
la source
codepen.io semble également afficher ce caractère. VIM et VI, notepad ++ l'affiche également.
rlemon
Merci @rlemon, a ajouté un exemple CodePen à la réponse. Beau site, je ne le savais pas.
bfavaretto
Ran dans ce problème tout en copiant / collant le code pour la classe testTwo de cette question SO en utilisant Chromium. Apparemment, l'analyseur s'est étouffé avec la coloration syntaxique du functionmot - clé, qui était invisible dans Vim jusqu'à ce que je le mette en surbrillance à l'aide de la méthode FAQ "Mettre en surbrillance tous les caractères non imprimables". Ahh, ce serait tellement bien s'il y avait un moyen de copier uniquement les caractères dans la plage de 32..127 (mais il y a probablement une application pour ça :))
ack
1
@bfavaretto, uniquement dans l'extrait de code en mode édition. Pas dans le corps de la question, aurait dû le mentionner. (Testé sur Chrome 43.0.2357.124 m)
Fernando Leal
1
De nombreux éditeurs de texte permettent de changer l'encodage des caractères d'un fichier. C'est extrêmement utile pour trouver des personnages offensants comme ceux-ci. Ma solution a été de passer temporairement de l'UTF-8 à un encodage ANSI, de supprimer les caractères invalides, puis de revenir en arrière. J'ai utilisé le freeware Notepad ++ sur Windows. EDIT: Il s'avère que j'ai manqué l'option Notepad ++ pour "Afficher tous les caractères". Même résultat, moins de tracas: D
mbargiel
64

pourquoi cherchez-vous ce problème dans votre code? Même si c'est copypassé.

Si vous pouvez voir ce qui se passe exactement après avoir enregistré le fichier dans un dossier synchronisé, vous verrez quelque chose comme *****à la fin du fichier. Ce n'est pas du tout lié à votre code.

Solution.

Si vous utilisez nginxdans une boîte vagabonde - ajoutez à la configuration du serveur:

sendfile off;

Si vous utilisez apachedans une boîte vagabonde - ajoutez à la configuration du serveur:

EnableSendfile Off;

Source du problème: bogue VirtualBox

Nikolay Fominyh
la source
6
Vous m'avez littéralement sauvé la journée. J'ai eu du mal avec Nginx + Vagrant pendant toute une soirée, et cela l'a résolu.
fradeve
2
Je ne m'attendais pas à ce que ce soit la bonne réponse (pour moi) mais ça l'était, merci beaucoup.
Charlotte
2
En fait, il a cessé de fonctionner. Là encore, il y a plusieurs couches de liens symboliques en jeu ici, donc je viens de défaire ce que je pouvais.
Charlotte
Merci - j'étais dans une boîte vagabonde avec nginx. J'ai également vu ce problème sur des configurations Apache similaires.
Cameron
pour apache: EnableSendfile Off
jamlee
7

Cela peut également se produire si vous copiez du code d'un autre document (comme un PDF) dans votre console et essayez de l'exécuter.

J'essayais d'exécuter un exemple de code à partir d'un livre Javascript que je lis et j'ai été surpris qu'il ne s'exécute pas dans la console.

Apparemment, la copie à partir du PDF introduit des caractères inattendus, illégaux et invisibles dans le code.

Kyle Pennell
la source
5

J'ai eu le même problème sur mon Mac et j'ai découvert que c'était parce que le Mac remplaçait les guillemets standard par des guillemets bouclés qui sont des caractères Javascript illégaux.

Pour résoudre ce problème, j'ai dû modifier les paramètres sur mon Mac Préférences Système => Clavier => Texte (onglet) décochez utiliser les guillemets intelligents et les tirets (la valeur par défaut a été vérifiée).

user3360944
la source
5

J'ai obtenu cette erreur dans Chrome lorsque j'avais une chaîne non terminée après la ligne vers laquelle l'erreur pointait. Après avoir fermé la chaîne, l'erreur a disparu.

Exemple avec erreur:

var file = files[i]; // SyntaxError: Unexpected token ILLEGAL

jQuery('#someDiv').innerHTML = file.name + " (" + formatSize(file.size) + ") "
    + "<a href=\"javascript: something('"+file.id+');\">Error is here</a>";

Exemple sans erreur:

var file = files[i]; // No error

jQuery('#someDiv').innerHTML = file.name + " (" + formatSize(file.size) + ") "
    + "<a href=\"javascript: something('"+file.id+"');\">Error was here</a>";
Ozzy
la source
2
J'ai dû exécuter un diff sur vos deux exemples pour comprendre la différence, et une fois que j'ai fait, j'ai tout de suite compris mon propre problème.
Ben Harold
3

Si vous exécutez un programme d'installation nginx + uwsgi, le problème principal est le bogue de la boîte virtuelle avec le fichier d'envoi, comme mentionné dans certaines des réponses. Cependant, pour le résoudre, vous devez désactiver sendfile dans nginx et uwsgi.

  1. Dans nginx.conf sendfile off

  2. uwsgi application / config --disable-sendfile

msrivas
la source
2

Lors de l'exécution d'OS X, le système de fichiers crée des fourches cachées de pratiquement tous vos fichiers, s'ils se trouvent sur un disque dur qui ne prend pas en charge HFS +. Cela peut parfois (ce qui m'est arrivé tout à l'heure) conduire à ce que votre moteur JavaScript essaie d'exécuter le data-fork au lieu du code que vous souhaitez qu'il exécute. Lorsque cela se produit, vous recevrez également

SyntaxError: Unexpected token ILLEGAL

car la fourchette de données de votre fichier contiendra le caractère Unicode U + 200B. La suppression du fichier fork de données fera que votre script exécutera votre code réel prévu, au lieu d'un fork de données binaires de votre code.

. que ce soit: Ces fichiers sont créés sur des volumes qui ne prennent pas en charge nativement les caractéristiques complètes des fichiers HFS (par exemple, les volumes ufs, les partages de fichiers Windows, etc.). Lorsqu'un fichier Mac est copié sur un tel volume, sa fourchette de données est stockée sous le nom habituel du fichier et les informations HFS supplémentaires (fourchette de ressource, codes de type et de créateur, etc.) sont stockées dans un deuxième fichier (au format AppleDouble), avec un nom qui commence par ". ". (Ces fichiers sont, bien sûr, invisibles en ce qui concerne OS-X, mais pas pour les autres OS; cela peut parfois être ennuyeux ...)

Spcaeyob
la source
1

Voici ma raison:

avant:

var path = "D:\xxx\util.s"

ce qui \uest une évasion, je l'ai compris en utilisant l'analyse JS de Codepen .

après:

var path = "D:\\xxx\\util.s"

et l'erreur corrigée

Miao1007
la source
0

J'ai eu ce même problème et il s'est produit parce que j'avais appuyé sur la touche Entrée lors de l'ajout de code dans une chaîne de texte.

Parce que c'était une longue chaîne de texte, je voulais tout voir sans avoir à faire défiler dans mon éditeur de texte, mais en appuyant sur Entrée, un caractère invisible a été ajouté à la chaîne, ce qui était illégal. J'utilisais Sublime Text comme éditeur.

Jordan Davis
la source
0

J'ai changé toutes les zones d'espace en & nbsp, juste comme ça et cela a fonctionné sans problème.

val.replace ("", "& nbsp");

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

Erdogan
la source
0

Je vais ajouter une réponse de plus à la pile. Ce problème pourrait également se produire en raison de l'encodage. Vous voulez que l'encodage utf8 soit du bon côté. Certains éditeurs utilisent par défaut utf16, ce qui peut provoquer des problèmes. Un moyen rapide de tester cela est, par exemple dans le code VS, de simplement recréer le même contenu mais d'utiliser l'éditeur local de vscode pour créer le fichier. J'espère que cela aide certains.

rezeli
la source