web-dev-qa-db-ja.com

「予期しないトークンILLEGAL」の明白な原因はない

私は私のコンソール上でこのJavaScriptエラーを得ています:

捕捉されないSyntaxError:予期せぬトークンILLEGAL

これは私のコードです:

var foo = 'bar';​

ご覧のとおり、とても単純です。構文エラーの原因は何でしょうか。

268
bfavaretto

エラー

コードがJavaScriptインタープリターによって解析されると、「トークン」と呼ばれる部分に分割されます。トークンを 4つの基本的なトークンタイプ の1つに分類できない場合、ほとんどの実装で "ILLEGAL"とラベル付けされ、このエラーがスローされます。

たとえば、不正な@文字、誤った位置の中括弧、大括弧、 "スマート引用符"、一重引用符が正しく囲まれていない(たとえばthis.run('dev1))などでjsファイルを実行しようとした場合も、同じエラーが発生します。

このエラーはさまざまな状況で発生する可能性があります。しかし、明らかな構文エラーや不正な文字がない場合は、非表示不正な文字が原因である可能性があります。それがこの答えの意味です。

しかし、私は違法なものを見ることはできません!

セミコロンの直後に、コード内に見えない文字があります。それは UnicodeのU+200Bゼロ幅のスペース 文字です(別名ZWSP、HTMLエンティティの​)。その文字はUnexpected token ILLEGAL JavaScriptシンタックスエラーを引き起こすことが知られています。

そしてそれはどこから来たのですか?

よくわかりませんが、私の賭けは jsfiddle です。そこからコードを貼り付けると、1つ以上のU+200B文字が含まれる可能性が非常に高いです。このツールは長い文字列のワードラップを制御するためにその文字を使用しているようです。

更新2013-01-07

最新の jsfiddle update の後、 codepenのように文字を赤いドット として表示しています。 どうやら、それ自身でU+200B文字をもう挿入していないので、今後この問題はそれほど頻繁に起こるべきではありません。

更新2015-03-17

Vagrant は、 VirtualBox のバグのため、この問題を引き起こすことがあります。解決方法は、 このブログ記事 に従って、nginxの設定でsendfile off;を設定するか、Apacheを使用している場合はEnableSendfile Offを設定することです。

Chrome開発者ツールから貼り付けられたコードにその文字が含まれている可能性があることも reports されていますが、現在のバージョン(OSXでは22.0.1229.79)では再現できませんでした。

どうやって見つけられるの?

キャラクターは見えません、それがそこにあることをどうやって知るのでしょうか?見えない文字を表示するようにエディタに依頼できます。ほとんどのテキストエディタはこの機能を持っています。たとえば、Vimはデフォルトでそれらを表示し、ZWSP<u200b>として表示されます。オンラインでデバッグすることもできます。 jsbin は、その文字をコードペインに赤い点として表示します(ただし、ページを保存して再ロードした後は削除されるようです)。 CodePen.ioもドット として表示し、保存後も保持します。

関連する問題

その性格は悪いことではありません、それは実際には非常に便利です。 このウィキペディアの例 は、長い文字列を次の行に折り返す場所を制御するためにそれを使用する方法を示しています。しかし、あなたが自分のマークアップに登場人物の存在を知らない場合、それは問題になるかもしれません。あなたがそれを文字列の中に持っている場合(例えば、目に見えるコンテンツを持たないDOM要素のnodeValue)、実際にはそうでないとき(たとえString.trimを適用した後でも)、そのような文字列は空になるでしょう。

ZWSPは、例えば this question で見られるように、2つの<div>要素の間に見つかると、余分な空白がHTMLページに表示されることもあります。この場合はjsfiddleでは再現できません。文字が無視されるためです。

もう1つの潜在的な問題:WebページのエンコーディングがUTF-8として認識されない場合、文字は実際に表示される可能性があります(たとえば、latin1の​など)。

ZWSPがCSSコード(インラインコード、または外部スタイルシート)に存在する場合、スタイルも正しく解析できないため、一部のスタイルは適用されません( this question のように)。

ECMAScriptの仕様

私はECMAScript仕様(バージョン 3 および 5.1 )にその特定の文字についての言及を見つけることができませんでした。現在のバージョンでは、 Section 7.1 で同様の文字(U+200CU+200D)に言及しています。これは、 "コメント、文字列リテラル、正規表現リテラルの外側"の場合、それらはIdentifierPartsとして扱われるべきです。これらの文字は、たとえば、変数名の一部になることがあります(そしてvar x\u200c;は実際に機能します)。

セクション7.2 は有効な空白文字(タブ、スペース、改行なしのスペースなど)をリストし、他のUnicode「スペース区切り文字」(カテゴリ「Z」)はすべて白として扱われるべきであると漠然と述べていますスペース。私はおそらくこの点に関してスペックを議論するのが最善の人ではないかもしれませんが、実際には実装(少なくともChromeとFirefox)はそれらをそれらとして扱うように見えるとき、U+200Bは空白と見なされるべきです予期しないトークン(またはその一部)が原因で構文エラーが発生しました。

492
bfavaretto

なぜあなたはあなたのコードの中でこの問題を探していますか?たとえコピーしたとしても。

あなたが見ることができるならば、同期されたフォルダーにファイルを保存した後に正確に何が起こっています - あなたはファイルの終わりに*****のような何かを見るでしょう。あなたのコードとはまったく関係ありません。

解決策。

Vagrantボックスでnginxを使用している場合 - サーバー設定に追加してください:

sendfile off;

VagrantボックスでApacheを使用している場合 - サーバー設定に追加してください:

EnableSendfile Off;

問題の原因: VirtualBoxバグ

63
Nikolay Fominyh

他のドキュメント(PDFなど)からコンソールにコードをコピーして実行しようとしている場合も同様です。

私が読んでいるJavascriptの本からいくつかのサンプルコードを実行しようとしていましたが、コンソールでは実行されないことに驚きました。

どうやらPDFからコピーすると、予期しない、違法で、見えない文字がコードに入ります。

7
Kyle Pennell

エラーが指す行の後に終端されていない文字列があると、このエラーがクロムで表示されました。文字列を閉じた後、エラーは消えました。

エラーのある例

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>";

エラーなしの例

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

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

私のMacでも同じ問題を抱えていましたが、それはMacが標準の引用符を違法なJavaScript文字である中引用符に置き換えていたためです。

これを直すには、私のMacのシステム環境設定=>キーボード=>テキスト(タブ)の設定を変更しなければなりませんでした。

5
user3360944

あなたがnginx + uwsgi setup vagrantを実行しているならば、主な問題はいくつかの答えで述べられているようにファイルを送ることでのバーチャルボックスバグです。しかしそれを解決するには、nginxとuwsgiの両方でsendfileを無効にする必要があります。

  1. Nginx.confのsendfileでオフ

  2. uwsgi application/config --disable-sendfile

3
msrivas

OS Xを実行しているとき、HFS +をサポートしていないハードドライブ上にある場合、ファイルシステムは基本的にすべてのファイルの隠れたフォークを作成します。これは時々(たった今私にも起こりましたが)あなたのJavaScriptエンジンが実行しようとしているコードの代わりにデータフォークを実行しようとすることにつながるかもしれません。これが起こるとき、あなたはまた受け取るでしょう

SyntaxError: Unexpected token ILLEGAL

あなたのファイルのデータフォークにはUnicodeのU + 200B文字が含まれるからです。データフォークファイルを削除すると、スクリプトはコードのバイナリデータフォークではなく、実際の目的のコードを実行します。

. whatever:これらのファイルは、HFSファイルの完全な特性をネイティブにサポートしていないボリューム(ufsボリューム、Windowsファイル共有など)上に作成されます。 Macファイルがそのようなボリュームにコピーされると、そのデータフォークはファイルの通常の名前で保存され、追加のHFS情報(リソースフォーク、タイプとクリエータコードなど)は2番目のファイル(AppleDoubleフォーマット)に保存されます。 "。 "で始まる名前で。 (もちろん、これらのファイルは、OS-Xに関する限りは見えませんが、他のOSには見えません。これは時々厄介です...)

2
Spcaeyob

これが私の理由です:

前:

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

どの\uはエスケープです、私は Codepen のanalyze JSを使ってそれを考え出しました。

後:

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

そしてエラーが修正されました

1
Miao1007

私はそのようにしてすべてのスペース領域を変更し、問題なく動作しました。

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

誰かに役立つことを願っています。

0
Erdogan

私はこれと同じ問題を抱えており、テキスト文字列にコードを追加するときにEnterキーを押したためにこの問題が発生しました。

それは私のテキストエディタでスクロールする必要なしに全部を見たかった長いテキスト文字列だったので、エンターを押すことは違法である文字列に見えない文字を追加しました。私は私の編集者としてSublime Textを使っていました。

0
Jordan Davis