“意外令牌非法”无可见原因;

我得到这个JavaScript错误在我的控制台:

未捕获SyntaxError:意外令牌非法

这是我的代码:

.
var foo = 'bar';​

It's super simple, as you can see. How could it be causing a syntax error?

309779 次浏览

这个错误

当代码被JavaScript解释器解析时,它被分解成称为“令牌”的片段。当一个令牌不能被归类到四种基本令牌类型中的一个时,它会被标记为“非法”;,并抛出此错误。

例如,如果你试图运行一个带有错误@字符、乱放的花括号、大括号、“智能引号”、没有正确括起来的单引号(例如this.run('dev1))等的js文件,也会引发同样的错误。

很多不同的情况都会导致这个错误。但如果没有任何明显的语法错误或非法字符,则可能是由invisible非法字符引起的。这就是我的答案。

但我没看到任何违法的东西!

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

它从何而来?

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

更新2013-01-07

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

更新2015-03-17

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

它也是报道,从Chrome开发人员工具粘贴的代码可能包括该字符,但我无法在当前版本(OSX上的22.0.1229.79)中重现。

我怎样才能发现它?

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

相关问题

这种性格并不是什么坏事,它实际上是相当有用的。维基百科上的这个例子演示了如何使用它来控制长字符串应该换行到下一行的位置。但是,如果您没有意识到标记上存在字符,这可能会成为一个问题。如果你把它放在字符串中(例如,没有可见内容的DOM元素的nodeValue),你可能会期望这样的字符串是空的,而实际上它不是空的(即使在应用String.trim之后)。

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

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

如果ZWSP出现在CSS代码(内联代码或外部样式表)中,样式也不能正确解析,因此一些样式不会被应用(如在这个问题中所见)。

ECMAScript规范

我在ECMAScript规范(版本3.5.1)中找不到任何提到这个特定的字符。当前版本在7.1节中提到了类似的字符(U+200CU+200D),这表明当“注释之外,字符串字面量和正则表达式字面量”时,它们应该被视为IdentifierParts。例如,这些字符可以是变量名的一部分(var x\u200c;确实有效)。

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

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

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

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

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

如果你能看到,在同步文件夹中保存文件后到底发生了什么-你会在文件末尾看到类似*****的东西。这和你的代码一点关系都没有。

解决方案。

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

sendfile off;

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

EnableSendfile Off;

问题来源:VirtualBox错误

如果你正在运行一个nginx + uwsgi安装流浪者,那么主要的问题是在一些答案中提到的发送文件的虚拟盒错误。然而,要解决这个问题,你必须在nginx和uwsgi中禁用sendfile。

    <李> < p > nginx.conf 李sendfile了< / p > < / >
  1. uwsgi application / config . 李——disable-sendfile < / p > < / >

我在我的mac上也有同样的问题,发现这是因为mac正在用不合法的javascript字符替换标准引号。

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

当我在错误指向的行后有一个未结束的字符串时,我在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>";

我也遇到了同样的问题,因为我在文本字符串中添加代码时按了enter键。

因为它是一个很长的文本字符串,我想看到它,而不必在我的文本编辑器中滚动,然而,按enter添加了一个不可见的字符字符串,这是非法的。我使用Sublime Text作为编辑器。

当运行OS X时,文件系统会为基本上所有文件创建隐藏的分叉,如果它们位于不支持HFS+的硬盘驱动器上。这有时会导致你的JavaScript引擎试图运行data-fork,而不是你想让它运行的代码。当这发生时,你也会收到

SyntaxError: Unexpected token ILLEGAL

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

.whatever:这些文件创建在不支持完全HFS文件特性的卷上(例如ufs卷,Windows文件共享等)。当Mac文件被复制到这样一个卷时,它的数据fork存储在文件的常规名称下,并且附加的HFS信息(资源fork,类型&创建者代码等)存储在第二个文件(AppleDouble格式)中,其名称以“。”。(当然,这些文件对OS- x来说是不可见的,但对其他OS则不然;这有时候很烦人…)

我把所有的空间区域都改成了 ,就像这样,它工作起来没有问题。

Val.replace (" ", " ");

我希望它能帮助到一些人。

以下是我的理由:

之前:

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

其中\u是一个转义,我通过使用Codepen的分析JS找到了它。

后:

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

错误被修正了

我将在堆中再添加一个答案。这个问题也可能因为编码而发生。您希望utf8编码是安全的。一些编辑器默认使用utf16,这可能会导致问题。一个快速的测试方法是,例如在VS code中,简单地重新创建相同的内容,但使用vscode的本地编辑器来创建文件。