Ответ 1
D'oh - вам нужно дважды закодировать: JSON.parse ожидает строку, конечно:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
Есть ли причины, по которым функция PHP json_encode не удаляет все JSON управляющие символы в строке?
Например, возьмите строку, которая охватывает две строки и имеет в ней управляющие символы (\ r\n "/\):
<?php
$s = <<<END
First row.
Second row w/ "double quotes" and backslash: \.
END;
$s = json_encode($s);
echo $s;
// Will output: "First row.\r\nSecond row w\/ \"double quotes\" and backslash: \\."
?>
Обратите внимание, что символы возврата каретки и новой строки не отображаются. Почему?
Я использую jQuery в качестве моей JS-библиотеки, и функция $.getJSON() отлично справится, когда вы полностью, 100% доверяете входящим данным. В противном случае я использую JSON.org library json2.js, как и все остальные. Но если вы попытаетесь разобрать эту закодированную строку, она выдает ошибку:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>); // Will throw SyntaxError
</script>
И вы не можете получить данные! Если вы удалите или убери \r\n "и\в этой строке, то JSON.parse() не будет вызывать ошибку.
Есть ли какая-либо существующая хорошая функция PHP для экранирования управляющих символов. Простая str_replace с поиском и заменой массивов не будет работать.
D'oh - вам нужно дважды закодировать: JSON.parse ожидает строку, конечно:
<script type="text/javascript">
JSON.parse(<?php echo json_encode($s) ?>);
</script>
function escapeJsonString($value) {
# list from www.json.org: (\b backspace, \f formfeed)
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
Я использую указанную выше функцию, которая ускользает от обратного слэша (должна быть первой в массивах) и должна иметь дело с formfeeds и backspaces (я не думаю, что \f
и \b
поддерживаются в PHP).
Я до сих пор не понял никакого решения без str_replace
..
Попробуйте этот код.
$json_encoded_string = json_encode(...);
$json_encoded_string = str_replace("\r", '\r', $json_encoded_string);
$json_encoded_string = str_replace("\n", '\n', $json_encoded_string);
Надеюсь, что это поможет...
$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"');
$replace = array("\\n", "\\r", "\\u", "\\t", "\\f", "\\b", "\/", "\"");
$encoded_string = str_replace($search, $replace, $json);
Это правильный способ
Преобразование в PHP из PHP не должно быть проблемой. PHP json_encode делает правильную кодировку, но переинтерпретирует то, что внутри java script может вызвать проблемы. Как
1) исходная строка - [строка с nnn новой строкой в ней] (где nnn - символ новой строки)
2) json_encode преобразует это значение в [string с "\\n" новой строкой в нем] (управляющий символ преобразован в "\\n" - Literal "\n"
3) Однако, когда вы печатаете это снова в литеральной строке, используя php echo, тогда "\\n" интерпретируется как "\n" и вызывает сердечную боль. Поскольку JSON.parse поймет буквально напечатанную "\n" как новую строку - управляющий символ (nnn)
чтобы обойти это: -
А) Сначала закодируйте json-объект в php с помощью json_enocde и получите строку. Затем запустите его через фильтр, который делает его безопасным для использования внутри html и java script.
В) используйте строку JSON, исходящую из PHP, как "литерал" и помещаем ее в одинарные кавычки вместо двойных кавычек.
<?php
function form_safe_json($json) {
$json = empty($json) ? '[]' : $json ;
$search = array('\\',"\n","\r","\f","\t","\b","'") ;
$replace = array('\\\\',"\\n", "\\r","\\f","\\t","\\b", "'");
$json = str_replace($search,$replace,$json);
return $json;
}
$title = "Tiger /new \\found \/freedom " ;
$description = <<<END
Tiger was caged
in a Zoo
And now he is in jungle
with freedom
END;
$book = new \stdClass ;
$book->title = $title ;
$book->description = $description ;
$strBook = json_encode($book);
$strBook = form_safe_json($strBook);
?>
<!DOCTYPE html>
<html>
<head>
<title> title</title>
<meta charset="utf-8">
<script type="text/javascript" src="/3p/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var strBookObj = '<?php echo $strBook; ?>' ;
try{
bookObj = JSON.parse(strBookObj) ;
console.log(bookObj.title);
console.log(bookObj.description);
$("#title").html(bookObj.title);
$("#description").html(bookObj.description);
} catch(ex) {
console.log("Error parsing book object json");
}
});
</script>
</head>
<body>
<h2> Json parsing test page </h2>
<div id="title"> </div>
<div id="description"> </div>
</body>
</html>
Поместите строку внутри одной кавычки в java script. Ввод строки JSON внутри двойных кавычек приведет к сбою синтаксического анализатора в марке атрибутов (что-то вроде { "id": "value" }). Никакое другое экранирование не требуется, если вы поместите строку как "литерал" и пусть JSON-парсер выполнит работу.
Возможно, я слепой, но в вашем примере они сбежали. Что насчет
<script type="text/javascript">
JSON.parse("<?php echo $s ?>"); // Will throw SyntaxError
</script>
(обратите внимание на разные кавычки)
Я не совсем понимаю, как работает var_export, поэтому я буду обновлять, если у меня возникнут проблемы, но это, похоже, работает для меня:
<script>
window.things = JSON.parse(<?php var_export(json_encode($s)); ?>);
</script>
$val = array ( "\n", "\ r" );
$string = str_replace ($ val, "", $string);
он удалит всю строку из строки json в php
Просто добавление в ответ Greg: вывод json_encode()
уже содержится в двойных кавычках ("
), поэтому нет необходимости окружать они с кавычками снова:
<script type="text/javascript">
JSON.parse(<?php echo $s ?>);
</script>
Управляющие символы не имеют особого значения в HTML, кроме новой строки в textarea.value. JSON_encode на PHP > 5.2 сделает это так, как вы ожидали.
Если вы просто хотите показать текст, вам не нужно идти за JSON. JSON предназначен для массивов и объектов в JavaScript (и индексированного и ассоциативного массива для PHP).
Если вам нужен фид строки для техасского тега:
$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */',' ',$s);
Это то, что я использую лично, и он никогда не работал. Первоначально имели подобные проблемы.
Источник script (ajax) примет массив и json_encode. Пример:
$return['value'] = 'test';
$return['value2'] = 'derp';
echo json_encode($return);
Мой javascript сделает вызов AJAX и получит эхо-сообщение "json_encode ($ return)" в качестве его ввода, а в script я буду использовать следующее:
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
когда "msg" является возвращаемым значением. Итак, для вас, что-то вроде...
var msg = '<?php echo $s ?>';
myVar = jQuery.parseJSON(msg.replace(/"/ig,'"'));
... может работать для вас.
Существует 2 решения, если не используется AJAX:
Запишите данные на входные данные и прочитайте их в JS:
<input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/>
Используйте addlashes
var json = '<?= addslashes(json_encode($data)) ?>';
При использовании любой формы Ajax в Интернете отсутствует подробная документация для формата ответов, полученных с сервера CGI. Некоторые примечания здесь и записи в stackoverflow.com указывают, что новые строки в возвращаемых текстах или json-данных должны быть экранированы для предотвращения бесконечных циклов (зависаний) в преобразовании JSON (возможно, созданных путем бросания неперехваченного исключения), независимо от того, выполняется ли это вручную с помощью jQuery или вручную Javascript система или библиотека JSON разбор звонков.
В каждом случае, когда программисты публикуют эту проблему, представлены неадекватные решения (чаще всего заменяя \n на\\n на отправляющей стороне), и дело отбрасывается. Их неадекватность обнаруживается при передаче строковых значений, которые случайно вставляют управляющие escape-последовательности, такие как имена путей Windows. Пример: "C:\Chris\Roberts.php", который содержит управляющие символы ^ c и ^ r, что может привести к преобразованию JSON строки { "file": "C:\Chris\Roberts.php" } в цикл навсегда. Один из способов генерации таких значений преднамеренно пытается передать предупреждения и сообщения об ошибках PHP с сервера на клиент, разумную идею.
По определению Ajax использует HTTP-соединения за кулисами. Такие соединения передают данные с использованием GET и POST, оба из которых требуют кодирования отправленных данных, чтобы избежать неправильного синтаксиса, включая управляющие символы.
Это дает достаточно намека на то, что кажется решением (требуется больше тестирования): использовать rawurlencode на стороне PHP (отправки) для кодирования данных и unescape на стороне Javascript (получающей) для декодирования данные. В некоторых случаях вы будете применять их ко всем текстовым строкам, в других случаях вы будете применять их только к значениям внутри JSON.
Если эта идея окажется правильной, можно создать простые примеры, чтобы помочь программистам на всех уровнях решить эту проблему раз и навсегда.