【问题标题】:Javascript parse error on '\u2028' unicode character'\u2028' unicode 字符上的 Javascript 解析错误
【发布时间】:2011-02-27 06:16:42
【问题描述】:

每当我在我的 javascript 源代码中使用 \u2028 字符文字并将内容类型设置为“text/html; charset=utf-8”时,我都会收到一个 javascript 解析错误。

例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>json</title>

    <script type="text/javascript" charset="utf-8">
    var string = '
    ';
    </script>
</head>
<body>

</body>
</html>

如果&lt;meta http-equiv&gt; 被忽略,一切都会按预期进行。我在 Safari 和 Firefox 上测试过,都出现了同样的问题。

关于为什么会发生这种情况以及如何正确解决这个问题(不删除编码)的任何想法?

编辑: 经过一番研究,具体问题是问题字符是使用 JSONP 返回的。然后浏览器将其解释为 u2028 作为换行符,并引发有关字符串中无效换行符的错误。

【问题讨论】:

  • 你从哪里得到解析错误?
  • 在线与var string = ' ';

标签: javascript unicode


【解决方案1】:

嗯,这是有道理的,因为您告诉浏览器 HTML 和脚本都使用 UTF-8,但是您指定了一个不是 UTF-8 编码的字符。当您指定“charset=UTF-8”时,您有责任确保传输到浏览器的字节实际上是 UTF-8。在这种情况下,Web 服务器和浏览器不会为您执行此操作。

【讨论】:

  • 那么,如何解决呢?该字符由网站用户输入。他的数据以 JSON 格式存储。每次我请求 JSON 时,都会出现解析错误,因为字符在那里。我不能只删除字符,因为客户端很可能会再次输入。
  • 根据 this 的 cmets 回答,这是一个有效的 UTF-8 字符,应该正确解析。
【解决方案2】:

你能用\u2028代替真正的字符吗?因为U+2028是unicode line seperator,浏览器会认为像\n这样的真正的换行符。

我们不能这样做

x = "

"

对吗?但我们是x = "\n",所以可能是同一个概念。

【讨论】:

  • Douglas Crockford 的 JSON 实现确实对字符串进行了转义,但仍会引发解析错误。在 Safari 中,使用了本机 JSON 实现,这也会引发解析错误。我们正在加载 jsonp,因此浏览器将在任何其他 javascript 有机会删除任何无效字符之前尝试解析它。我可能不得不解决这个服务器端。
  • 是的@klaaspieter,可能在服务器端,如果你必须这样做,也可以转义\u2029
  • 顺便说一下,我已经测试了一些,Douglas Crockford 的实现没有抛出解析错误。
【解决方案3】:

好吧,回答我自己的问题。

通常 JSON 解析器会去除这些问题字符,因为我正在检索 JSONP,我没有使用 JSON 解析器,而是浏览器在调用回调时尝试解析 JSON 本身。

修复它的唯一方法是确保服务器在请求 JSONP 资源时永远不会返回这些字符。

附言 我的问题是关于 u2028,根据Douglas Crockford's json2 library,以下所有字符都可能导致这些问题:

'\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff'

【讨论】:

【解决方案4】:

是的,这是 JavaScript 语言的一个特性,记录在 ECMAScript 标准(第 3 版第 7.3 节)中,U+2028 和 U+2029 字符计为行尾。因此,JavaScript 解析器将以与换行相同的方式处理任何未编码的 U+2028/9 字符。由于不能在字符串文字中添加换行符,因此会出现语法错误。

这是 JSON 设计中的一个不幸的疏忽:它实际上不是 JavaScript 的正确子集。原始 U+2028/9 字符在 JSON 中的字符串文字中有效,并且将被 JSON.parse 接受,但在 JavaScript 本身中则不然。

因此,如果您确定它明确地\u-转义这些字符,则使用 JSON 解析器生成 JavaScript 代码才是安全的。有些会,有些不会;许多\u-转义所有非ASCII字符,这样可以避免问题。

【讨论】:

  • 这很有帮助。解决方法是转义 JSON,然后解析客户端。例如,Ruby/Rails 的 stackoverflow.com/questions/9691611/… 告诉您在服务器端模板中执行 $.parseJSON("#{j xyz.to_json}")。
  • 更好的是:JSON.parse(#{j.to_json.inspect}) 会将其呈现为带有\uXXXX 的字符串,用于处理任何不规则字符。
  • 您可以将 JSON 插入到脚本标签中,并将其类型设置为“application/json”。这应该避免将 UTF-8 文本解析为 JavaScript。页面加载完成后,可以通过传递脚本标签的innerHTML作为参数,使用JSON.parse()解析JSON。
  • 不确定我是否会称其为 JSON 中的疏忽,以及 Javascript 中的设计缺陷;将这些字符作为换行符包含在内是奇怪且出乎意料的,其他文本数据格式不会这样做。但是对于 JSON,虽然它的起源来自 Javascript 子集,但它多年来一直没有与 Javascript 绑定,并且规范没有声称它会是一个子集,或者这将是一个目标。建议不要评估它,而是正确解析。因此,除了 JSONP 的使用之外,引用写作是否必要甚至是一件好事并不完全清楚。
  • 第 10 版(非常新):“更新的语法包括……允许字符串文字中的 U+2028(行分隔符)和 U+2029(段落分隔符)与 JSON 对齐。”来自ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
猜你喜欢
  • 2014-02-09
  • 2016-04-07
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2015-05-09
  • 1970-01-01
相关资源
最近更新 更多