没有可见的原因导致“意外令牌非法”


270

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

Uncaught SyntaxError:意外的令牌非法

这是我的代码:

var foo = 'bar';​

如您所见,它非常简单。它怎么会引起语法错误?


9
对于未来的读者:如果您在使用Vagrant时遇到此错误-此答案也可能有帮助:stackoverflow.com/questions/9479117/…–
OZ_

如果您在WordPress中遇到这种情况,请从functions.php中加入脚本。我有一个特定的模板,可以直接从模板中调用JS。切换到wp_head或wp_footer中的条件队列可以解决此问题。
Alpesh Shah 2014年

7
主持人的注意:我在这里删除了一堆实际上没有回答问题的答案。这不是(我重复一遍)不是列出所有可能导致此错误的JavaScript中可能做的事情的地方。该问题具有非常具体的情况,不涉及任何一种情况,并且所有这些示例无法回答该问题。
animuson

3
哇,SO警察对这个问题进行了实地调查。幸运的是,一些相关的信息在删除的答案中仍然可见。
cdonner

Answers:


493

错误

当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还将其显示为点,并且即使保存后也将其保留。

相关问题

这个角色还不错,实际上很有用。Wikipedia上的此示例演示了如何将其用于控制​​将长字符串包装到下一行的位置。但是,如果您不知道标记中字符的存在,则可能会出现问题。如果您将其包含在字符串中(例如,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)似乎将它们视为意外情况。令牌(或其中一部分),导致语法错误。


codepen.io也似乎显示此字符。VIM和VI以及notepad ++也会显示它。
rlemon 2012年

感谢@rlemon,在答案中添加了CodePen示例。不错的网站,我不知道。
bfavaretto 2012年

在使用Chromium 从这个SO问题复制/粘贴testTwo类的代码时遇到了这个问题。显然,解析器阻塞了function关键字的语法高亮显示,该关键字在Vim中不可见,直到我使用“突出显示所有不可打印的字符”常见问题解答方法将其高亮显示为止。嗯,如果有一种方法可以只复制32..127范围内的字符,那就太好了(但是可能有一个用于此的应用程序:))
ack

1
@bfavaretto,仅在编辑模式下的代码段中。不在正文中,应该提到这一点。(在Chrome 43.0.2357.124 m上测试)
Fernando Leal

1
许多文本编辑器允许切换文件的字符编码。这对于查找此类冒犯性人物非常有用。我的解决方案是暂时从UTF-8切换为ANSI编码,删除无效字符,然后再切换回去。我在Windows上使用了免费的Notepad ++软件。编辑:原来我错过了“显示所有字符”的记事本++选项。同样的结果,更少的麻烦:D
mbargiel 16-3-22

64

为什么要在代码中寻找这个问题?即使被复制粘贴。

如果您看到了,将文件保存在同步文件夹中后到底发生了什么-您会*****在文件末尾看到类似的信息。它根本与您的代码无关。

解。

如果您nginx在“无业游民”框中使用-添加到服务器配置中:

sendfile off;

如果您apache在“无业游民”框中使用-添加到服务器配置中:

EnableSendfile Off;

问题源:VirtualBox错误


6
你从字面上拯救了我。我已经和Nginx + Vagrant纠缠了整整一个晚上,这解决了它。
fradeve 2014年

2
不要期望这是正确的答案(对我来说),但它是,非常感谢。
夏洛特

2
实际上,它停止工作了。再说一次,这里有多层符号链接在起作用,所以我只是不知所措。
夏洛特

谢谢-我当时正和nginx混在一起。我在类似的Apache设置上也看到了此问题。
卡梅隆

for Apache:EnableSendfile Off
Jamlee

7

如果要将代码从另一个文档(例如PDF)复制到控制台并尝试运行它,也可能会发生这种情况。

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

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


5

我在Mac上遇到了同样的问题,发现这是因为Mac用卷曲的引号代替了标准引号,而卷曲的引号是非法的javascript字符。

为了解决这个问题,我必须更改我的mac系统偏好设置=> Keyboard => Text(tab)上的设置,取消选中使用智能引号和破折号(选中了默认值)。


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

示例无错误:

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

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

2
我必须对您的两个示例进行比较以找出差异,然后,我立即找出了自己的问题。
本·哈罗德

3

如果您正在运行nginx + uwsgi安装程序,那么主要问题是某些答案中提到的带有发送文件的虚拟盒错误。但是要解决该问题,您必须在nginx和uwsgi中都禁用sendfile。

  1. 在nginx.conf中关闭sendfile

  2. uwsgi应用程序/配置--disable-sendfile


2

在运行OS X时,如果文件系统位于不支持HFS +的硬盘驱动器上,则文件系统会创建几乎所有文件的隐藏分支。有时(这在我现在刚刚发生)可能导致您的JavaScript引擎尝试运行数据叉而不是您打算运行的代码。发生这种情况时,您还将收到

SyntaxError: Unexpected token ILLEGAL

因为您文件的数据分支将包含Unicode U + 200B字符。删除数据分支文件将使您的脚本运行您的实际预期代码,而不是代码的二进制数据分支。

无论如何:这些文件是在本身不支持完整HFS文件特征的卷上创建的(例如ufs卷,Windows文件共享等)。将Mac文件复制到这样的卷时,其数据派生存储在文件的常规名称下,其他HFS信息(资源派生,类型和创建者代码等)存储在第二个文件中(AppleDouble格式),名称以“。开头。(就OS-X而言,这些文件当然是不可见的,但对于其他OS而言则不可见;这有时可能会令人讨厌...)


1

这是我的原因:

之前:

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

\u是一个逃脱,我通过使用Codepen解决的分析JS来解决。

后:

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

和错误修复


0

我遇到了同样的问题,它的发生是因为我在文本字符串中添加代码时按下了回车键。

因为这是一个很长的文本字符串,所以我想查看所有内容而不必在文本编辑器中滚动,但是按回车键会在字符串中添加一个不可见的字符,这是非法的。我使用Sublime Text作为编辑器。


0

就像那样,我将所有空间区域都更改为&nbsp,并且工作正常。

val.replace(“”,“&nbsp”);

希望对您有所帮助。


0

我将再增加一个答案。也可能由于编码而发生此问题。您希望utf8编码是安全的。默认情况下,某些编辑器使用utf16,这可能会引起问题。一种快速的测试方法是,例如,在VS代码中,只需重新创建相同的内容,但使用vscode的本地编辑器即可创建文件。希望这会有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.