Javascript解码JSON字符串,其中包含一个编码字符串


Javascript decode JSON string which contains an encoded string

我有以下PHP代码:

    $foo = new stdClass();
    $foo->test='hello world';
    $bar = new stdClass();
    $bar->foo = json_encode($foo);
    $encoded_string = json_encode($bar);

$encoded_string包含:

{"foo":"{'"test'":'"hello world'"}"}

我想解析这个字符串从javascript(使用jQuery的$.parseJSON为例):

var data = $.parseJSON('{"foo":"{'"test'":'"hello world'"}"}');
console.log(data);

我希望记录如下内容:

Object {foo: '{"test":"hello world"}'}

但我得到一个Unexpected token t错误时运行它(使用铬)

我如何在Javascript中解析这个json字符串?如果有人想试试,这里有一把小提琴

您遇到的问题是json_encode的输出是不是意味着直接用作JavaScript中的字符串。

json_encode输出一个可用的JavaScript对象:

<?php
$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = json_encode($foo);
$encoded_string = json_encode($bar);
?>
var a = <?php $encoded_string ?>;
console.log(a.foo); // produces '{"test":"hello world"}'

如果希望无需解析字符串值的JSON输出,则只需对$encoded_string进行双编码:

<?php
$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = json_encode($foo);
$encoded_string = json_encode(json_encode($bar));
?>
var aStr = <?php $encoded_string ?>;
var a = JSON.parse(aStr);
console.log(a.foo); //same as before

当然,您应该避免使用服务器端语言来生成JavaScript代码,而是将数据设置为data-*属性或可以通过AJAX请求的JSON源。

当从服务器(或从属性)请求数据时,它将作为一个正确转义的JavaScript字符串,这就是需要JSON.parse来解析对象的地方。

你的代码应该是

$foo = new stdClass();
$foo->test='hello world';
$bar = new stdClass();
$bar->foo = $foo;
$encoded_string = json_encode($bar);

只要json在末尾编码一次,在另一端开始解码一次。


至于jsfiddle,你没有考虑到字符串在成为"javascript内存中的字符串"之前要经过额外的解码层。

在这种情况下设置字符串字面值的正确方法是(JS-JSON-JSON):

data = $.parseJSON('{"foo":"{'''"test'''":'''"hello world'''"}"}');
console.log($.parseJSON(data.foo));

简单地反转您所做的编码步骤。http://jsfiddle.net/Jmjjp/2/

问题是JSON的双重编码。如果需要将数据保留为字符串,您想要的解决方案是

$bar->foo = addslashes(json_encode($foo));

代码返回它应该返回的内容。

当json_encodein $bar, $bar->foo是字符串时。该字符串被转义以产生正确的输出。

$bar->foo = json_encode($foo);

应为$bar->foo = $foo

你需要转义保护内引号的斜杠:

JSON.parse('{"foo":"{''"test''":''"hello world''"}"}');
// == Object {foo: '{"test":"hello world"}'}