jQuery.parseJSON выдает ошибку «Invalid JSON» из-за экранированной одинарной кавычки в JSON
172419 просмотра
7 ответа
Я делаю запросы к моему серверу, используя 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" }
Это нормально? Нет ли способа правильно передать одинарную кавычку через JSON?
Автор: Felix Источник Размещён: 12.11.2019 09:31Ответы (7)
325 плюса
Согласно диаграмме конечного автомата на веб-сайте JSON допускаются только экранированные символы двойных кавычек, а не одинарные. Символы одинарных кавычек не должны быть экранированы:
Обновление - больше информации для тех, кто заинтересован:
Дуглас Крокфорд конкретно не говорит, почему спецификация JSON не допускает экранированные одинарные кавычки в строках. Однако во время обсуждения JSON в Приложении E JavaScript: Хорошие части он пишет:
Цели разработки JSON должны были быть минимальными, переносимыми, текстовыми и подмножеством JavaScript. Чем меньше нам нужно договориться о взаимодействии, тем легче нам взаимодействовать.
Поэтому, возможно, он решил разрешить определять строки только с помощью двойных кавычек, поскольку это еще одно правило, с которым должны согласиться все реализации JSON. В результате невозможно, чтобы одиночный символ кавычки в строке случайно завершил строку, потому что по определению строка может заканчиваться только символом двойной кавычки. Следовательно, нет необходимости разрешать экранирование символа одинарной кавычки в формальной спецификации.
Рытье немного глубже, Крокфорд в org.json реализация JSON для Java является более допустимым и делает позволяют одиночные кавычки:
Тексты, создаваемые методами 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;
...
В верхней части метода информационный комментарий:
Формальный формат 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 );
},
Насколько мне известно, эти реализации придерживаются только официальной спецификации JSON и не принимают одинарные кавычки, следовательно, jQuery также не принимает.
Автор: Justin Ethier Размещён: 16.02.2010 06:4916 плюса
Если вам нужна одиночная кавычка внутри строки, так как \ 'не определена спецификацией, используйте \u0027
см. Http://www.utf8-chartable.de/ для всех из них
редактировать: пожалуйста, извините за неправильное использование обратных слов в комментариях. Я имел в виду обратную косую черту. Я хочу сказать, что в случае, если у вас есть вложенные строки внутри других строк, я думаю, что может быть более полезным и читабельным использовать юникод вместо множества обратных слешей, чтобы избежать одной кавычки. Однако, если вы не вложены, проще вставить туда просто старую цитату.
Автор: slf Размещён: 16.09.2011 02:415 плюса
Я понимаю, в чем проблема, и когда я смотрю на спецификации, становится ясно, что одиночные кавычки без экранирования должны быть правильно проанализированы.
Я использую функцию jQuery.parseJSON jquery для разбора строки 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) . "]";
Последний шаг - сохранение строки в кодировке JSON в переменной JS:
<script type="text/javascript">
employees = jQuery.parseJSON('<?=$marker; ?>');
</script>
Если я использую «» вместо «», он все равно выдает ошибку.
РЕШЕНИЕ:
Единственное, что сработало для меня, - это использовать битовую маску JSON_HEX_APOS для преобразования одинарных кавычек:
json_encode($tmp, JSON_HEX_APOS);
Есть ли другой способ решения этой проблемы? Мой код неправильный или плохо написан?
Спасибо
Автор: Erik Čerpnjak Размещён: 30.10.2014 08:023 плюса
Когда вы отправляете одинарную цитату в запросе
empid = " T'via"
empid =escape(empid)
Когда Вы получаете значение, включающее одинарную кавычку
var xxx = request.QueryString("empid")
xxx= unscape(xxx)
Если вы хотите найти / вставить значение, которое включает в себя одну кавычку в запросе
xxx=Replace(empid,"'","''")
2 плюса
Похожая проблема - использование CakePHP для вывода JavaScript-блока JavaScript с использованием нативного PHP json_encode
. $contractorCompanies
содержит значения, которые имеют одинарные кавычки и, как объяснено выше и ожидается json_encode($contractorCompanies)
, не экранирует их, потому что это допустимый JSON
<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".(json_encode($contractorCompanies)."' );"); ?>
Добавляя addlashes () вокруг строки, закодированной в JSON, вы избегаете кавычек, позволяющих Cake / PHP выводить правильный код JavaScript в браузер. Ошибки JS исчезают.
<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".addslashes(json_encode($contractorCompanies))."' );"); ?>
Автор: chopstik
Размещён: 12.12.2014 04:17
0 плюса
Интересно. Как вы генерируете свой JSON на стороне сервера? Используете ли вы библиотечную функцию (например, json_encode
в PHP), или вы строите строку JSON вручную?
Единственное, что привлекает мое внимание, это апостроф ( \'
). Поскольку вы используете двойные кавычки, как вы и должны делать, вам не нужно избегать одинарных кавычек. Я не могу проверить, действительно ли это является причиной вашей ошибки jQuery, так как я сам еще не обновился до версии 1.4.1.
0 плюса
Я пытался сохранить объект JSON из XHR-запроса в атрибут data5 * HTML5. Я попробовал многие из вышеперечисленных решений безуспешно.
В конечном итоге я заменил одинарную кавычку '
на код '
с помощью регулярного выражения после вызова метода stringify () следующим образом:
var productToString = JSON.stringify(productObject);
var quoteReplaced = productToString.replace(/'/g, "'");
var anchor = '<a data-product=\'' + quoteReplaced + '\' href=\'#\'>' + productObject.name + '</a>';
// Here you can use the "anchor" variable to update your DOM element.
Автор: BoCyrill
Размещён: 14.04.2017 12:10
Вопросы из категории :
- javascript Как определить, какой из указанных шрифтов был использован на веб-странице?
- javascript Валидация клиентской стороны ASP.Net
- javascript Длина объекта JavaScript
- javascript Получение текста из выпадающего списка
- javascript Скрипт входа со скрытыми кнопками
- javascript Как автоматически изменить размер текстовой области с помощью Prototype?
- jquery Прокрутка переполненных DIV с помощью JavaScript
- jquery Экранирование строк HTML с помощью jQuery
- jquery Как сравнить HTML-сущность с JQuery
- jquery Есть ли функция "существует" для jQuery?
- jquery Как удалить все параметры в окне выбора, а затем добавить один вариант и выбрать его с помощью jQuery?
- jquery Получение идентификатора элемента, который вызвал событие
- json Безопасное превращение строки JSON в объект
- json Как я могу "красиво" отформатировать вывод JSON в Ruby on Rails?
- json Сериализация JSON в jQuery
- json Можете ли вы использовать запятую в JSON-объекте?
- json Можно ли использовать комментарии в формате JSON?
- json Могу ли я подавать RSS в формате JSON?