我的JS代码中有“零宽空格”字符。它们是从哪里来的?

55

我正在使用NetBeans IDE 7.0.1开发Web应用程序的前端。最近我遇到了一个非常严重的错误,但我最终解决了它。

假设我有这样的代码

var element = '<input size="3" id="foo" name="elements[foo][0]" />';
$('#bar').append(element);

我注意到当我发现在Chrome浏览器中size属性不起作用时出了问题(没有在其他浏览器中检查)。当我在检查器中打开该元素时,它被解释为类似于:

<input id="&quot;3&quot;" name="&quot;elements[foo][0]&quot;" 
    size="&quot;foo&quot;" />

这有点奇怪。在手动逐字重新输入“element”字符串后,错误就消失了。当我撤销这个更改时,我注意到Netbeans警告我代码中有一些Unicode字符,即\u200b,即'='之后,在']['之间和字符串结尾处都有零宽度空格。因此,该字符串看起来正常,因为零宽度空格没有显示,但在转义它们后,我的字符串就变成了。

'<input size=\u200b"3" id=\u200b"foo" name=\u200b"elements[foo]\u200b[0]" />\u200b'

现在问题是我到底从哪里得到它们的?

我不确定我从哪里复制了element的代码,但它肯定是以下来源之一:

  • Netbeans编辑器的HTML模板文件的另一个窗格;
  • Google Chrome检查器中的“复制为HTML”操作;
  • Google Chrome源代码视图页面(非常有疑问)。

但我无法用其中任何一个重现这个错误。

我使用的是Windows 7下的Netbeans 7.0.1和Google Chrome 13.0。没有键盘切换器或其他类似程序正在运行。此外,我使用Git进行版本控制,但我没有拉取那段代码,所以Git很少有责任。我的同事也不可能开这样的恶作剧,因为他们都很有礼貌。

你们有什么建议可以让我知道是谁搞砸了我的代码吗?


1
可怕。我希望你能追踪它。 - RichieHindle
谢谢,@RichieHindle。我放弃了自己追踪它的想法,希望社区能够提供帮助。毕竟,只要我知道如何修复它(扫描源代码中的"\u200b"出现),它就不那么可怕了。但我很好奇这是从哪里来的。 - Hnatt
@Hnatt:你的第二行代码是否在调用jQuery?如果是,请尝试在继续使用它之前使用escape()和/或encode()来“alert” var element的内容;你可以尝试重新编码append,绕过jQuery(使用getElementsByTagName(),append()),以明确地证明jQuery不是万恶之源? - MikeD
@Hnatt/2:如果使用jQuery,您会建议使用哪个版本……也许有人试图复制这个代码时使用了不同的版本。 - MikeD
2
@MikeD 这是jQuery 1.4.2版本,但与该错误无关,因为这些零长度空格是在我的代码中粘贴的,而不是由脚本生成的。我试图弄清楚的是我是如何将其复制到那里的。 - Hnatt
5个回答

58

以下是我的猜测。

我觉得可能是谷歌浏览器检查器。搜索Chromium源代码时,我发现了以下代码块

    if (hasText)
        attrSpanElement.appendChild(document.createTextNode("=\u200B\""));

    if (linkify && (name === "src" || name === "href")) {
        var rewrittenHref = WebInspector.resourceURLForRelatedNode(node, value);
        value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
        attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
    } else {
        value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
        var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
        attrValueElement.textContent = value;
    }

很有可能我在这里只是在做无用功,但看起来在显示属性时插入了零宽度空格(用于软文本换行?)。也许“复制为HTML”功能没有正确地删除它们?

更新

在使用Chrome元素检查器后,我几乎确定那是你多余的\u200b出现的地方。请注意,由于插入了零宽度空格,该行可以在可见空格之后以及在=或由/([\/;:\)\]\}])/匹配的字符之后换行。

chrome inspector screenshot

很抱歉,我无法复制您的问题,其中它们会不经意地包含在您的剪贴板中(我在Win XP上使用Chrome 13.0.782.112)。如果您能够重现此行为,提交错误报告肯定是值得的。

我不明白如何在“=”和“\”之间插入\u200b。但是在“][”的情况下,据我所见,似乎是完全可能的。谢谢Shawn! - Hnatt
引用代码块前的那一行是 .appendChild(document.createTextNode("=\u200B\""))。我猜这就是 = 后面的 \u200B 出现的地方。将更新答案以包括该行。 - Shawn Chin
我无法重现它。但是,无论如何,感谢您的回答。搜索Chromium代码似乎是捕捉那个混蛋的最佳方式。 - Hnatt
我还在想为什么我无法复现它。也许有一些if(theMoonIsFull)的条件。如果没有其他能够复现这个错误的答案,我会在一天内接受你的答案。 - Hnatt
我接受你的答案,以表达对你努力的赞赏(也因为它看起来非常一致)。让我复制这些字符的方式保持神秘。也许主要原因是我的手有点歪,运气不太好。必须说,当这件事发生时,月亮确实是满月,所以我会等到下一个满月并尝试复制这个错误! - Hnatt

10

7

正如Shawn Chin先生已经提到的,我在从一个网页复制jquery代码时偶然遇到了这个问题。

发生时间:从Google Chrome Version 41.0.2272.118 m(未测试其他浏览器)复制文本到Dreamweaver代码窗口。这会复制一些不需要的字符,就像这里发生的一样。

你从网页上复制了文本:

$('.btn-pageMenu').css('display'​​​​​​​​​​​​​​​​​​​​​​​​​​​,'block');​​​​​​

幕后,这就是使那行代码实现的东西

<code><span class="pun">&#8203;</span><span class="pln">$</span><span class="pun">(</span><span class="str">'.btn-pageMenu'</span><span class="pun">).</span><span class="pln">css</span><span class="pun">(</span><span class="str">'display'</span><span class="pun">&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;,</span><span class="str">'block'</span><span class="pun">);&#8203;&#8203;&#8203;&#8203;&#8203;&#8203;</span></code>

如果将其复制到像您提到的高级编辑器(如Dreamweaver)之类的编辑器中,则浏览器会出现错误,可能是JavaScript代码失败了。

Uncaught SyntaxError: Unexpected token ILLEGAL

解决方案:当出现这种情况时,暂时使用记事本,直到大公司修复问题。这与浏览器关系不大,更多的是与编辑器有关。

0

经过超过6年的时间,我遇到了同样的问题,但我能够重现它。

我正在从这个博客学习JavaScript,其中包含代码片段。每当我将一个片段中的所有代码复制并粘贴到JS Fiddle或JS Bin的JavaScript编辑器中时,我会在代码中看到一些红色标记。以下是上述博客文章中第一个代码片段在JS FiddleJS Bin中的屏幕截图。将鼠标悬停在其中一个红色标记上会显示提示:"\u200b"(零宽度空格)。

我正在使用Linux Ubuntu 16.04,并且如果我将代码粘贴到我的编辑器之一(Atom 1.22.1或Geany 1.32)中,然后在Web浏览器中打开文件,我会在控制台中看到以下错误:

  • Chrome 63 --> SyntaxError:无效或意外的标记
  • Firefox 57 --> SyntaxError:非法字符

我希望这可以在一定程度上阐明为什么这些零宽空格会被复制到剪贴板中。


0

我在当前项目中遇到了与零宽空格字符'\u200b'类似的问题。我需要处理从服务器返回的JSON对象。其中,包含 '[at]' 的电子邮件对象需要用 '@' 字符替换。令人惊讶的是,一些对象的电子邮件地址在 '@' 周围和内部散布了许多 '空格'。

长话短说,我使用Postman检查并且审查了返回的JSON作为原始数据。以下是一个原始示例:

johndoe[at]\u200bxyz.org

在所有那些有问题的电子邮件地址上,我能看到字符 '\u200b'。由于只有少数电子邮件地址受影响,我手动删除了该字符。服务器从Sharepoint获取数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接