由于JSON中的单引号转义,jQuery.parseJSON抛出"无效的JSON"错误

Fel*_*lix 202 javascript jquery json

我正在向我的服务器发出请求jQuery.post(),我的服务器正在返回JSON对象(如{ "var": "value", ... }).但是,如果任何值包含单引号(正确转义\'),jQuery无法解析其他有效的JSON字符串.这是我的意思的一个例子(在Chrome的控制台中完成):

data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }

$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }
Run Code Online (Sandbox Code Playgroud)

这是正常的吗?有没有办法通过JSON正确传递单个引用?

Jus*_*ier 325

根据JSON网站上的状态机图,只允许转义双引号字符,而不是单引号.单引号字符不需要转义:

http://www.json.org/string.gif


更新 - 有兴趣的人的更多信息:


Douglas Crockford没有具体说明为什么JSON规范不允许字符串中的转义单引号.但是,在他在JavaScript:The Good Parts的附录E中讨论JSON时,他写道:

JSON的设计目标是最小化,可移植,文本和JavaScript的子集.为了实现互操作,我们需要达成一致意见的越少,我们就越容易互操作.

所以也许他决定只允许使用双引号定义字符串,因为这是所有JSON实现必须达成一致的规则.因此,字符串中的单引号字符不可能意外终止字符串,因为根据定义,字符串只能以双引号字符终止.因此,不需要允许在正式规范中转义单引号字符.


挖一点点更深,Crockford的org.json的Java实现JSON的是更允许的,不会允许单引号字符:

toString方法生成的文本严格遵循JSON语法规则.构造者在他们接受的文本中更宽容:

...

  • 字符串可以用'(单引号)引用.

这是由JSONTokener源代码确认的.该nextString方法接受转义的单引号字符,并将它们视为双引号字符:

public String nextString(char quote) throws JSONException {
    char c;
    StringBuffer sb = new StringBuffer();
    for (;;) {
        c = next();
        switch (c) {

        ...

        case '\\':
            c = this.next();
            switch (c) {

            ...

            case '"':
            case '\'':
            case '\\':
            case '/':
                sb.append(c);
                break;
        ...
Run Code Online (Sandbox Code Playgroud)

该方法的顶部是一个内容丰富的评论:

正式的JSON格式不允许单引号中的字符串,但允许实现接受它们.

所以有些实现会接受单引号 - 但你不应该依赖它.许多流行的实现在这方面都是相当严格的,并且将拒绝包含单引号字符串和/或转义单引号的JSON.


最后要将其与原始问题联系起来,jQuery.parseJSON首先尝试使用浏览器的本机JSON解析器或加载的库(如适用的json2.js)(在侧面说明是jQuery逻辑所基于的库,如果JSON未定义) .因此jQuery只能像底层实现一样宽松:

parseJSON: function( data ) {
    ...

    // Attempt to parse using the native JSON parser first
    if ( window.JSON && window.JSON.parse ) {
        return window.JSON.parse( data );
    }

    ...

    jQuery.error( "Invalid JSON: " + data );
},
Run Code Online (Sandbox Code Playgroud)

据我所知,这些实现只遵循官方的JSON规范,不接受单引号,因此jQuery也没有.

  • UPDATE :: JQuery在使用JSON时非常严格.如果你尝试提醒($.parseJSON("[\"Ciao \\'\"]")); 由于贾斯汀的报道,它不起作用 (4认同)
  • "*Crockford的org.json实现JSON for Java是允许的,允许单引号字符*"#这只是一个好的做法:[健全性原则](http://en.wikipedia.org/wiki/Robustness_principle) (2认同)

slf*_*slf 16

如果您需要在字符串中使用单引号,因为规范未定义\',\u0027 请参阅http://www.utf8-chartable.de/以获取所有这些内容

编辑:请原谅我在评论中滥用反对词这个词.我的意思是反斜杠.我的观点是,如果你在其他字符串中嵌套了字符串,我认为使用unicode而不是大量的反斜杠来逃避单引号会更有用和可读.如果你没有嵌套,那么在那里放一个普通的旧报价确实更容易.

  • 不,只需使用简单的单引号即可. (28认同)
  • 你为什么需要反叛?如果您有一个像"foo'bar'"这样的字符串,那么您只需将单引号保留为未转义状态. (3认同)
  • 当你嵌套时 (3认同)
  • 正是我在寻找的东西.我正在尝试将json字符串作为js字符串var写入页面,并将其用单引号括起来,并且只要属性值中包含单引号,它就会提前终止.现在我只需在代码中执行json.Replace("'","\ u0027"),然后再将其写入页面. (3认同)

Eri*_*jak 5

我了解问题出在哪里,当我查看规格时,很清楚应该正确解析未转义的单引号。

我正在使用jquery的jQuery.parseJSON函数来解析JSON字符串,但是当用json_encode准备的数据中存在单引号时,仍然会出现解析错误。

看起来像这样的实现(PHP-服务器端)可能是一个错误:

$data = array();

$elem = array();
$elem['name'] = 'Erik';
$elem['position'] = 'PHP Programmer';
$data[] = json_encode($elem);

$elem = array();
$elem['name'] = 'Carl';
$elem['position'] = 'C Programmer';
$data[] = json_encode($elem);

$jsonString = "[" . implode(", ", $data) . "]";
Run Code Online (Sandbox Code Playgroud)

最后一步是将JSON编码的字符串存储到JS变量中:

<script type="text/javascript">
employees = jQuery.parseJSON('<?=$marker; ?>');
</script>
Run Code Online (Sandbox Code Playgroud)

如果我使用“”而不是“”,它仍然会引发错误。

解:

对我而言唯一有效的方法是使用位掩码JSON_HEX_APOS转换单引号,如下所示:

json_encode($tmp, JSON_HEX_APOS);
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以解决这个问题?我的代码是错误的还是写得不好?

谢谢