没有明显的“意外令牌非法”原因

No visible cause for "Unexpected token ILLEGAL"

提问人:bfavaretto 提问时间:10/4/2012 最后编辑:Fernando Lealbfavaretto 更新时间:12/28/2019 访问量:312001

问:

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

未捕获的语法错误:意外令牌非法

这是我的代码:

var foo = 'bar';​

正如你所看到的,这非常简单。它怎么会导致语法错误?

javascript 语法错误 非法字符

评论

9赞 OZ_ 10/9/2013
对于未来的读者:如果您在使用 Vagrant 时遇到此错误 - 这个答案也会有所帮助:stackoverflow.com/questions/9479117/......
0赞 Alpesh Shah 10/9/2014
如果您在 WordPress 中遇到这种情况,请将函数 .php 中的脚本排入队列。我有一个特定的模板,我直接从模板调用 JS。在 wp_head 或 wp_footer 中切换到条件排队解决了此问题。
8赞 animuson 10/13/2014
主持人注:我在这里删除了一堆实际上并没有回答问题的答案。我再说一遍,这不是一个列出你可以在 JavaScript 中执行的所有可能导致此错误的事情的地方。这个问题有一个非常具体的情况,不涉及任何这些场景,所有这些例子根本无法回答这个问题。
4赞 cdonner 2/11/2015
哇,SO 警察对这个问题进行了现场调查。幸运的是,一些相关信息在已删除的答案中仍然可见。

答:

496赞 bfavaretto 10/4/2012 #1

错误

当 JavaScript 解释器解析代码时,它会被分解成称为“标记”的部分。当令牌无法归类为四种基本令牌类型之一时,它会在大多数实现中被标记为“非法”,并引发此错误。

例如,如果您尝试运行带有流氓字符、错位的大括号、括号、“智能引号”、单引号未正确括起来(例如)等的 js 文件,则会引发相同的错误。@this.run('dev1)

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

但我看不出任何违法的东西!

代码中有一个不可见的字符,紧跟在分号之后。它是Unicode U + 200B零宽度空格字符(又名HTML实体)。已知该字符会导致 JavaScript 语法错误。ZWSP​Unexpected token ILLEGAL

它从何而来?

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

更新 2013-01-07

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

更新 2015-03-17

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

还有报道称,从 Chrome 开发者工具粘贴的代码可能包含该字符,但我无法在当前版本(OSX 上为 22.0.1229.79)中重现该字符。

我怎样才能发现它?

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

相关问题

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

ZWSP还会导致 HTML 页面上显示额外的空格,例如,当它位于两个元素之间时(如本问题所示)。这种情况甚至无法在 jsfiddle 上重现,因为该字符在那里被忽略了。<div>

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

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

ECMAScript 规范

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

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

评论

0赞 rlemon 10/5/2012
codepen.io 似乎也显示此字符。VIM 和 VI,记事本++ 也会显示它。
0赞 bfavaretto 10/5/2012
感谢@rlemon,在答案中添加了一个 CodePen 示例。不错的网站,我不知道。
0赞 ack 12/15/2013
使用 Chromium 从这个 SO 问题复制/粘贴 testTwo 类的代码时遇到了这个问题。显然,解析器在关键字的语法高亮上窒息了,这在 Vim 中是不可见的,直到我使用“突出显示所有不可打印的字符”FAQ 方法高亮它。啊,如果有一种方法可以只复制 32..127 范围内的字符,那就太好了(但可能有一个适用于该:)的应用程序)function
1赞 Fernando Leal 6/11/2015
@bfavaretto,仅在编辑模式下的代码片段中。不在问题的正文中,应该提到这一点。(在Chrome 43.0.2357.124 m上测试)
1赞 mbargiel 3/22/2016
许多文本编辑器允许切换文件的字符编码。这对于查找此类冒犯性角色非常有用。我的解决方案是暂时从 UTF-8 切换到 ANSI 编码,删除无效字符,然后切换回来。我在 Windows 上使用了免费软件 Notepad++。编辑:原来我错过了“显示所有字符”的Notepad ++选项。相同的结果,更少的麻烦:D
7赞 Kyle Pennell 1/29/2014 #2

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

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

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

64赞 Nikolay Fominyh 5/6/2014 #3

为什么要在代码中寻找这个问题?甚至,如果它是复制粘贴的。

如果您能看到,将文件保存到同步文件夹中后究竟发生了什么 - 您将在文件末尾看到类似的东西。它与您的代码完全无关。*****

溶液。

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

sendfile off;

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

EnableSendfile Off;

问题来源:VirtualBox Bug

评论

6赞 fradeve 7/9/2014
你真的拯救了我的一天。我和 Nginx + Vagrant 斗争了一整个晚上,这解决了它。
2赞 Belladonna 8/1/2014
没想到这是正确的答案(对我来说),但它是,非常感谢。
2赞 Belladonna 8/2/2014
实际上,它停止了工作。再说一次,这里有多层符号链接在起作用,所以我只是撤消了我能做的。
0赞 Cameron 7/29/2015
谢谢 - 我和 nginx 在一个流浪的盒子里。我也在类似的 Apache 设置上看到了这个问题。
0赞 jamlee 3/21/2016
对于 apache:EnableSendfile 关闭
3赞 kodeKoala 3/24/2015 #4

如果您正在运行nginx + uwsgi设置流浪者,那么主要问题是发送文件的虚拟盒子错误,如某些答案中所述。但是,要解决它,您必须在 nginx 和 uwsgi 中禁用 sendfile。

  1. 在 nginx.conf 中 发送文件关闭

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

5赞 user3360944 4/2/2015 #5

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

为了解决这个问题,我不得不更改我的 mac 上的设置:系统偏好设置=>键盘=>文本(选项卡),取消选中使用智能引号和破折号(默认已选中)。

5赞 Ozzy 9/21/2015 #6

当我在错误指向的行之后有一个未终止的字符串时,我在 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赞 Ben Harold 11/22/2015
我不得不对你的两个例子进行差异以找出差异,一旦我这样做了,我立即发现了我自己的问题。
0赞 Jordan Davis 12/12/2015 #7

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

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

2赞 Spcaeyob 2/15/2016 #8

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

SyntaxError: Unexpected token ILLEGAL

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

.whatever :这些文件是在本机不支持完整 HFS 文件特征的卷上创建的(例如 ufs 卷、Windows 文件共享等)。当 Mac 文件被复制到这样的卷时,其数据分支存储在文件的常规名称下,而其他 HFS 信息(资源分支、类型和创建者代码等)存储在第二个文件(AppleDouble 格式)中,名称以“.”开头。(当然,就OS-X而言,这些文件是不可见的,但对其他操作系统则不可见;这有时可能很烦人......

0赞 Erdogan 2/25/2016 #9

我将所有空间区域更改为&nbsp,就像那样,它可以正常工作。

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

我希望它对某人有所帮助。

1赞 Miao1007 8/9/2016 #10

这是我的原因:

以前:

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

这是一种逃避,我通过使用 Codepen 的 analyze JS 弄清楚了。\u

后:

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

并修复了错误

0赞 rezeli 12/28/2019 #11

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