ChatGPT解决这个技术问题 Extra ChatGPT

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

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

Uncaught SyntaxError: Unexpected token ILLEGAL

这是我的代码:

var foo = 'bar';​

如您所见,它非常简单。它怎么可能导致语法错误?

对于未来的读者:如果您在使用 Vagrant 时遇到此错误 - 此答案也可能会有所帮助:stackoverflow.com/questions/9479117/…
如果您在 WordPress 中遇到这种情况,请将 functions.php 中的脚本排入队列。我有一个特定的模板,我直接从模板中调用 JS。切换到 wp_head 或 wp_footer 中的条件入队解决了这个问题。
版主注:我在这里删除了一堆实际上并没有回答问题的答案。这不是,我重复一遍,不是列出你可以在 JavaScript 中执行的所有可能导致此错误的事情的地方。这个问题有一个非常具体的情况,不涉及任何这些场景,所有这些例子都不能回答这个问题。
哇,SO 警察在这个问题上度过了愉快的一天。幸运的是,一些相关信息在已删除的答案中仍然可见。

C
Community

错误

当 JavaScript 解释器解析代码时,它会被分解成称为“令牌”的片段。当令牌不能归类为 four basic token types 之一时,在大多数实现中它会被标记为“非法”,并引发此错误。

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

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

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

代码中有一个不可见字符,就在分号之后。它是 Unicode U+200B Zero-width space 字符(又名 ZWSP,HTML 实体 ​)。已知该字符会导致 Unexpected token ILLEGAL JavaScript 语法错误。

它是从哪里来的?

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

更新 2013-01-07 在最新的 jsfiddle 更新之后,它现在像 codepen 一样将字符显示为红点。显然,它也不再单独插入 U+200B 字符,所以从现在开始这个问题应该不那么频繁了。由于 VirtualBox 中的错误,更新 2015-03-17 Vagrant 似乎有时也会导致此问题。根据this blog post,解决方案是关闭sendfile;在您的 nginx 配置中,如果您使用 Apache,则启用 EnableSendfile Off。

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

我怎样才能发现它?

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

相关问题

那个角色还不错,其实还挺有用的。 This example on Wikipedia 演示了如何使用它来控制长字符串应在何处换行到下一行。但是,如果您不知道该角色在您的标记中的存在,它可能会成为一个问题。如果您将它包含在字符串中(例如,没有可见内容的 DOM 元素的 nodeValue),您可能希望这样的字符串为空,而实际上并非如此(即使在应用 String.trim 之后)。

ZWSP 还可能导致在 HTML 页面上显示额外的空白,例如在两个 <div> 元素之间发现它时(如 this question 所示)。这种情况甚至无法在 jsfiddle 上重现,因为该字符在那里被忽略。

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

如果 CSS 代码(内联代码或外部样式表)中存在 ZWSP,则样式也无法正确解析,因此无法应用某些样式(如 this question 所示)。

ECMAScript 规范

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

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


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

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

如果您可以看到,在同步文件夹中保存文件后究竟发生了什么 - 您会在文件末尾看到类似 ***** 的内容。它根本与您的代码无关。

解决方案。

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

sendfile off;

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

EnableSendfile Off;

问题来源:VirtualBox Bug


你真的拯救了我的一天。我整晚都在用 Nginx + Vagrant 苦苦挣扎,这解决了它。
没想到这是正确的答案(对我来说),但确实如此,非常感谢。
实际上,它停止了工作。然后这里又有多层符号链接在起作用,所以我只是尽我所能。
谢谢 - 我在一个 nginx 的流浪盒子里。我也在类似的 Apache 设置中看到了这个问题。
对于 apache:EnableSendfile Off
K
Kyle Pennell

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

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

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


u
user3360944

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

要解决此问题,我必须更改我的 mac System Preferences=>Keyboard=>Text(tab) 上的设置取消选中使用智能引号和破折号(默认已选中)。


O
Ozzy

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

我不得不对你的两个示例进行比较以找出差异,一旦我这样做了,我立即找出了我自己的问题。
m
msrivas

如果您正在运行 nginx + uwsgi setup vagrant,那么主要问题是一些答案中提到的带有发送文件的虚拟框错误。但是要解决它,您必须在 nginx 和 uwsgi 中禁用 sendfile。

在 nginx.conf sendfile off uwsgi application/config --disable-sendfile


S
Spcaeyob

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

SyntaxError: Unexpected token ILLEGAL

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

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

戈登戴维森@http://www.westwind.com/reference/OS-X/invisibles.html


M
Miao1007

这是我的理由:

前:

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

其中 \u 是一个转义,我通过使用 Codepen 的分析 JS 弄清楚了。

后:

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

并修复了错误


J
Jordan Davis

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

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


E
Erdogan

我将所有空间区域更改为  ,就像那样,它没有问题。

val.replace(" ", " ");

我希望它可以帮助某人。


r
rezeli

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