"Unexpected token ILLEGAL"没有明显原因

bfa*_*tto 269 javascript syntax-error illegal-characters

我在我的控制台上收到此JavaScript错误:

未捕获的SyntaxError:意外的标记ILLEGAL

这是我的代码:

你可以看到它非常简单.怎么会导致语法错误?

bfa*_*tto 494

错误

当JavaScript解释器解析代码时,它会被分解为称为"令牌"的片段.当令牌不能被分类为四种基本令牌类型之一时,在大多数实现中它被标记为"ILLEGAL",并且抛出此错误.

例如,如果您尝试运行带有恶意@字符,错位的大括号,括号,"智能引号",单引号未正确包含(例如this.run('dev1))等的js文件,则会引发相同的错误.

许多不同的情况都可能导致此错误.但是,如果您没有任何明显的语法错误或非法字符,则可能是由不可见的非法字符引起的.这就是这个答案的意思.

但我看不出任何违法行为!

在分号后面的代码中有一个不可见的字符.它是Unicode U+200B零宽度空格字符(又名ZWSPHTML实体​).已知该字符会导致Unexpected token ILLEGALJavaScript语法错误.

它来自哪里?

我无法确定,但我的赌注是jsfiddle.如果您从那里粘贴代码,则很可能包含一个或多个U+200B字符.似乎该工具使用该字符来控制长字符串上的自动换行.

更新2013-01-07

在最新的jsfiddle更新之后,它现在将该字符显示为像codepen 一样的红点.显然,它也U+200B不再单独插入字符,所以从现在开始这个问题应该不那么频繁了.

更新2015-03-17

由于VirtualBox中的错误,Vagrant似乎有时也会导致此问题.根据这篇博客文章,解决方案是sendfile off;在你的nginx配置中设置,或者EnableSendfile Off如果你使用Apache.

报道,从Chrome开发人员工具粘贴的代码可能包含该字符,但我无法使用当前版本(OSX上的22.0.1229.79)重现该代码.

我怎么能发现它?

角色是看不见的,我们怎么知道它在那里?您可以要求编辑显示隐形字符.大多数文本编辑器都具有此功能.例如,Vim默认显示它们,ZWSP显示为<u200b>.您也可以在线调试它:jsbin在其代码窗格中将字符显示为红点(但在保存和重新加载页面后似乎将其删除).CodePen.io也将其显示为点,并在保存后保留.

相关问题

这个角色并不坏,它实际上非常有用.维基百科上的这个示例演示了如何使用它来控制长字符串应该包装到下一行的位置.但是,如果您不知道角色在您的标记上的存在,它可能会成为一个问题.如果你有一个字符串(例如,nodeValue没有可见内容的DOM元素),你可能希望这样的字符串是空的,而实际上它不是(即使在应用之后String.trim).

ZWSP还可以在HTML页面上显示额外的空格,例如,当在两个<div>元素之间找到它时(如此问题所示).这种情况甚至不能在jsfiddle上重现,因为那里的字符被忽略了.

另一个潜在问题:如果网页的编码未被识别为UTF-8,则可能实际显示该字符(​例如,如latin1).

如果ZWSPCSS代码(内联代码或外部样式表)中存在,则样式也无法正确解析,因此某些样式不会被应用(如此问题所示).

ECMAScript规范

我在ECMAScript规范(版本35.1)上找不到任何关于该特定字符的提及.当前版本在7.1节中提到了类似的字符(U+200CU+200D),它表示在"注释,字符串文字和正则表达式文字之外" 时应将它们视为s.例如,这些字符可以是变量名称的一部分(并且确实有效).IdentifierPartvar x\u200c;

第7.2节列出了有效的空格字符(例如制表符,空格,不间断空格等),并且模糊地提到任何其他Unicode"空格分隔符"(类别"Zs")应该被视为空格.我可能不是讨论这方面规格的最佳人选,但在我看来U+200B应该被视为白色空间,实际上实现(至少Chrome和Firefox)似乎将它们视为意外令牌(或一部分),导致语法错误.

  • emacs的解决方案:http://www.emacswiki.org/emacs/FindingNonAsciiCharacters (2认同)

Nik*_*nyh 63

为什么要在代码中查找此问题?甚至,如果它是复制的.

如果你可以看到,在同步文件夹中保存文件后到底发生了什么 - 你会看到类似于*****文件末尾的内容.它完全与你的代码无关.

解.

如果您nginx在vagrant box 中使用- 添加到服务器配置:

sendfile off;
Run Code Online (Sandbox Code Playgroud)

如果您apache在vagrant box 中使用- 添加到服务器配置:

EnableSendfile Off;
Run Code Online (Sandbox Code Playgroud)

问题来源:VirtualBox Bug

  • 你真的节省了我的一天.我和Nginx + Vagrant一​​起度过了整个晚上,这解决了它. (6认同)
  • 是*不*期望这是正确的答案(对我而言)但是,非常感谢. (2认同)
  • 实际上,它停止了工作.然后再次在这里有多层符号,所以我只是解开了我能做的事情. (2认同)

Kyl*_*ell 7

如果您将代码从其他文档(如PDF)复制到控制台并尝试运行它,也可能会发生这种情况.

我试图从我正在阅读的Javascript书中运行一些示例代码,并且很惊讶它没有在控制台中运行.

显然,从PDF中复制会在代码中引入一些意外的,非法的和不可见的字符.


小智 5

我在我的Mac上遇到了同样的问题,发现这是因为Mac正在用非常javascript字符的引号替换标准引号.

要解决此问题,我必须更改我的mac系统首选项=>键盘=>文本(选项卡)上的设置取消选中使用智能引号和破折号(默认已选中).


Ozz*_*zzy 5

当我在错误指向的行后面有一个未终止的字符串时,我在chrome中出现了这个错误.关闭字符串后,错误就消失了.

错误示例:

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>";
Run Code Online (Sandbox Code Playgroud)

示例没有错误:

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

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

  • 我不得不在你的两个例子上运行差异以找出差异,一旦我做了,我立即想出了我自己的问题. (2认同)