2013-06-18 2 views
2

Я следующий код PHP:Javascript расшифровывает JSON строку, которая содержит закодированную строку

$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 ошибку при выполнении его (с помощью хрома)

Как я могу разобрать эту строку JSON в JavaScript? Here's a fiddle, если кто-то хочет попробовать.

ответ

3

Проблема, с которой вы столкнулись, состоит в том, что вывод 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-* attribute, либо как источник JSON, который можно запросить с помощью AJAX.

Когда данные запрашиваются с сервера (или из атрибута), он будет как правильно экранированная строка JavaScript, где JSON.parse будет необходим для синтаксического анализа объекта.

+0

Это имеет смысл и, очевидно, является правильным способом обработки json-строк; спасибо за хорошее объяснение. – periklis

0

Код возвращает именно то, что он должен вернуть.

когда json_encodein $ bar, $ bar-> foo - это строка. эта строка экранирована для получения правильного вывода.

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

должен быть $bar->foo = $foo

+0

Моя проблема в том, что $ bar содержит свойства json_encoded. Функция правильная; как мне получить объект в javascript? – periklis

+0

Я не хочу, чтобы внутренняя кодированная строка не была проанализирована ($ foo в этом примере); Я хочу, чтобы он остался как есть и только получил «внешний» объект – periklis

+0

Мне не удалось понять, в чем проблема или почему мой ответ не решает вашу проблему:/ – Pinoniq

0

вам нужно, чтобы избежать косых черт, защищающие внутренние кавычки:

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

Проблемы заключается двойная кодировка в формате JSON. Решение, которое вы хотите, если вам нужно сохранить данные в виде строки является

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

+0

Подумайте о кодировании и расшифровке, например о размещении элементов в вложенных блоках. 'addslashes' не является подходящей функцией для кодирования строки для ее хранения в другом поле. Можно просто называть 'json_encode (json_encode ($ foo))', но реальный основной вопрос заключается в том, почему это необходимо в первую очередь. – zzzzBov

+0

Согласовано. Ответ Пининька должен быть достаточным. «Произвольные данные, поступающие из другого источника, который может или не может быть уже обработан json», должны быть обработаны сначала, чтобы проверить, какие данные попадают перед его кодировкой (возможно, снова). – scum

1

Ваш код должен быть

$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/

Смежные вопросы