Как избежать специальных символов при построении строки JSON?

200

Вот моя строка

{
    'user': {
        'name': 'abc',
        'fx': {
            'message': {
                'color': 'red'
            },
            'user': {
                'color': 'blue'
            }
        }
    },
    'timestamp': '2013-10-04T08: 10: 41+0100',
    'message': 'I'mABC..',
    'nanotime': '19993363098581330'
}    

Здесь сообщение содержит одну кавычку, которая совпадает с кавычкой, используемой в JSON. Что я делаю, так это заполняю строку из пользовательских данных, таких как сообщение. Итак, мне нужно избежать тех особых сценариев, которые нарушают код. Но кроме замены строки, есть ли способ заставить их убежать, но все же позволить HTML обработать их обратно к правильному сообщению?

dinesh707
источник
45
JSON использует только двойные кавычки, а не одинарные, см. Json.org
Niels Bom
4
В RFC 4627 говорится, что синтаксические анализаторы должны иметь возможность анализировать совместимый JSON (параграф 4) и могут поддерживать дополнительные расширения не-JSON. Тем не менее, пункт 5 подчеркивает, что все производители (генераторы) ДОЛЖНЫ производить ТОЛЬКО 100% -ный JSON-совместимый. Создание JSON с символами кадра, которые не нуждаются в экранировании, является особенно плохой идеей. Пожалуйста, подумайте о замене апострофов кавычками. ietf.org/rfc/rfc4627.txt
Luv2code
3
@ Luv2code Несмотря на то, что ваши замечания остаются верными, обратите внимание, что вы ссылаетесь на устаревшую спецификацию. При чтении RFC всегда используйте версию tools.ietf.org/html , а не текстовую версию. Версии HTML легче читать и ссылаться на подразделы, и, что наиболее важно, в верхней части версий HTML находится список всех последующих RFC, которые обновляют или устаревают тот, который вы читаете. Если бы вы зашли на tools.ietf.org/html/rfc4627, вы бы увидели, что RFC 4627 устарел и был заменен RFC 7159 .
Марк Амери
3
Для людей, читающих это в будущем, RFC 7159, в свою очередь, устарел от tools.ietf.org/html/rfc8259
Йорам ван ден Бозем,

Ответы:

286

Строка JSON должна быть заключена в двойные кавычки, в соответствии со спецификацией , поэтому вам не нужно экранировать '.
Если вам нужно использовать специальный символ в вашей строке JSON, вы можете избежать его, используя \символ.

Посмотрите этот список специальных символов, используемых в JSON:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character


Тем не менее, даже если это полностью противоречит спецификации, автор может использовать \'.

Это плохо, потому что:

  • Это противоречит спецификации
  • Это больше не допустимая строка JSON

Но это работает, как вы хотите этого или нет.

Для новых читателей всегда используйте двойные кавычки для ваших строк JSON.

AlexB
источник
30
"одиночные кавычки строк json" ? Это нонсенс; строки в JSON могут быть только в двойных кавычках. Попробуйте JSON.parse("'foo'")в консоли браузера, например, и наблюдайте SyntaxError: Unexpected token '. Спецификация JSON очень проста и понятна . В JSON нет escape-последовательности для одинарных кавычек, а строка JSON не может быть заключена в одинарные кавычки.
Марк Амери
15
Даже якобы уточняющее обновление к этому ответу плохо. Хотя технически верно, это вводит в заблуждение , чтобы сказать , что вы «не нужно» , чтобы избежать ', во многом таким же образом , что это технически верно , но вводит в заблуждение , чтобы сказать , что по закону вам не нужно детям убийство. Правильнее было бы сказать, что вы не можете убежать '. \'является недопустимой escape-последовательностью, и если вы используете ее, то ваш JSON не является допустимым JSON, и любой JSON-анализатор захлебнется им. (Конечно, JavaScript JSON.parseи Python json.loadsделают.)
Марк Эмери
2
Этот ответ остается бессмысленным после многих правок. Вы ошибочно утверждаете, что использование строк в одинарных кавычках в JSON и \'escape-последовательности «работает, как вы хотите или нет» . Это неверно Я призываю вас продемонстрировать любой парсер JSON в популярном использовании, который не захлебывается строками в одинарных кавычках или \'последовательностью. Я уже указывал, что JSON.parse("'foo'")и JSON.parse('"\\\'"') (в JavaScript) и json.loads("'foo'")и json.loads('"\\\'"')(в Python) оба вызывают исключения. На чем основано утверждение, что использование этих конструкций "работает"?
Марк Амери
10
@ Luv2code интересная цитата. Вы немного неверно истолковали это; это не означает, что любой персонаж может быть убран, если поставить перед ним обратную косую черту. Более полная цитата: «Любой символ может быть экранирован. Если символ находится в базовой многоязычной плоскости (от U + 0000 до U + FFFF), то он может быть представлен в виде шестизначной последовательности . ... В качестве альтернативы, есть два последовательность символов экранирует представления некоторых популярных символов. "(выделено мной). Это говорит, что вы можете убежать 'как \u0027, а не то , что вы можете избежать как \'.
Марк Амери
2
@ Luv2code, тем не менее, это означает, что мой комментарий с голосованием, в котором говорится, что «ты не можешь сбежать '» (и сравниваю такой акт с убийством детей!) Технически неверен; Точнее сказать, что вы можете избежать этого, просто не так \'. Я не осознавал, что версия спецификации RFC ссылается на последовательности как \u0027способ «избежать» символов, которые они представляют. Ключевой момент, который \'является незаконным, тем не менее, остается верным и важным.
Марк Амери
362

Я потрясен присутствием высокооплачиваемой дезинформации по такому часто обсуждаемому вопросу об основной теме.

Строки JSON нельзя заключать в одинарные кавычки . Различные версии спецификации ( оригинал Дугласа Крокфорда, версия ECMA и версия IETF ) утверждают, что строки должны заключаться в двойные кавычки. Это не теоретический вопрос и не вопрос мнения, как это принято в настоящее время; любой анализатор JSON в реальном мире выдаст ошибку, если вы попытаетесь проанализировать строку в одинарных кавычках.

Версия Крокфорда и ECMA даже отображает определение строки, используя красивую картинку, которая должна ясно дать понять смысл:

Изображение, показывающее определение строки из спецификации JSON

На симпатичной картинке также перечислены все допустимые escape-последовательности в строке JSON:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u с последующим четырехзначным числом

Обратите внимание, что вопреки бессмыслице в некоторых других ответах здесь, \'никогда не допустимая escape-последовательность в строке JSON. Так не должно быть, потому что строки JSON всегда заключаются в двойные кавычки.

Наконец, вам обычно не нужно думать о экранировании символов при программной генерации JSON (хотя, конечно, вы будете это делать при ручном редактировании, скажем, файла конфигурации на основе JSON). Вместо этого сформируйте структуру данных, которую вы хотите кодировать, используя любые типы карт, массивов, строк, чисел, логических и нулевых значений, которые есть у вашего языка, а затем закодируйте ее в JSON с помощью функции кодирования JSON. Такая функция, вероятно, встроена в любой язык, который вы используете, например, в JavaScript JSON.stringify, PHP json_encodeили Python.json.dumps, Если вы используете язык, который не имеет такой встроенной функциональности, вы можете найти библиотеку JSON для разбора и кодирования. Если вы просто используете язык или библиотечные функции для преобразования вещей в JSON и обратно, вам даже не нужно знать правила экранирования JSON. Вот что должен был сделать ошибочный вопрос, задаваемый здесь.

Марк Эмери
источник
4 шестнадцатеричных байта или клев ?
Leetbacoon
36

Все говорят о том, как избежать строкового литерала 'в 'кавычках. Здесь есть гораздо большая проблема: строковые литералы в одинарных кавычках не являются допустимыми JSON . JSON основан на JavaScript, но это не одно и то же. Если вы пишете литерал объекта внутри кода JavaScript, хорошо; если вам действительно нужен JSON, вам нужно использовать ".

С двойными кавычками вам не нужно будет избегать '. (И если вы хотите получить литерал "в строке, вы бы использовали \".)

Дэвид Кнайп
источник
1
Привет, ты сказал с двойными кавычками, тебе не нужно будет избегать '. Например, если у меня есть строковое значение "Member's_id" : 4, вы говорите, что его не нужно экранировать? По-видимому, у меня проблема, когда он выдает ошибку неправильной кодировки: UTF-8 и читается как Member�s. Это сгенерированный вручную файл JSON.
Shubham
1
'в строковом литерале JSON нельзя экранировать. Вы скопировали и вставили это откуда-то? Может быть, это действительно, а \u2019не апостроф. Мое предположение: кто-то напечатал его в MS Word, который превратил его в кавычку, потому что он думает, что знает лучше. Грамматически, старый добрый апостроф символа ASCII (или 'известный \x27как «одинарная кавычка» до сих пор) - это то, что вам нужно. Но все равно было бы неплохо исправить проблему кодировки вашего персонажа на случай, если возникнут другие подобные проблемы. Поэтому выберите кодировку символов и используйте ее как для чтения, так и для записи. Или уйти, используя \u.
Дэвид Книп
7

Большинство из этих ответов либо не отвечают на вопрос, либо излишне длинны в объяснении.

Итак, JSON использует только двойные кавычки, мы получаем это!

Я пытался использовать JQuery AJAX для отправки данных JSON на сервер, а затем позже вернуть ту же информацию. Лучшее решение вопроса, который я нашел, было использовать:

var d = {
    name: 'whatever',
    address: 'whatever',
    DOB: '01/01/2001'
}
$.ajax({
    type: "POST",
    url: 'some/url',
    dataType: 'json',
    data: JSON.stringify(d),
    ...
}

Это спасет персонажей для вас.

Это также было предложено Марком Амери, отличный ответ, кстати

Надеюсь, это кому-нибудь поможет.

Надрать задницу
источник
0

Может быть, я опоздал на вечеринку, но это будет разбор / побег одиночной кавычки (не хочу вступать в битву при разборе против побега) ..

JSON.parse("\"'\"")
YankTHEcode
источник
0

Ответьте на прямой вопрос:
для безопасности замените требуемый символ на \ u + 4-значный-hex-значение

Пример: если вы хотите избежать апострофа, замените его на \ u0027.
D'Amico становится D \ u0027Amico.

ОТЛИЧНАЯ ССЫЛКА: http://es5.github.io/x7.html#x7.8.4

https://mathiasbynens.be/notes/javascript-escapes

Луиджи д'Амико
источник
-1 для ссылок. Вопрос касается JSON, но ваши ссылки связаны с JavaScript и содержат список escape-последовательностей, которые недопустимы в JavaScript \'.
Марк Амери
Спасибо Марк - я действительно просто хотел дать альтернативный угол - в зависимости от того, кто прибывает сюда, может оказаться полезным. Но я понимаю вашу точку зрения о JSON и Javascript - спасибо за то, что вы были ниндзя на форумах.
Луиджи Д'Амико,
0

Используйте encodeURIComponent () для кодирования строки.

Например. var product_list = encodeURIComponent (JSON.stringify (product_list));

Вам не нужно декодировать его, так как веб-сервер автоматически делает то же самое.

Санджу Канияматтам
источник
0

Использование литералов шаблона ...

var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;
Ruben
источник
-2

Я думаю, что мы все согласны, что jsons с одинарными кавычками не настоящие jsons. Как бы то ни было, нам все еще нужно решить вопрос о том, чтобы уйти "внутри строки json в двойных кавычках, в отсутствие библиотек, чтобы сделать это для нас.

Замена каждого «на \» НЕ ДОСТАТОЧНА: пользователь может ввести ввод: \, и синтаксический анализ, опять же, не удастся (подумайте почему).

Вместо этого сначала замените каждый \ на \ (двойной обратный слеш). Только тогда замените каждое "с \" (обратный слеш с последующим ").

Том Блиц
источник
-2

Чтобы разрешить одинарные кавычки в строке двойных кавычек для целей json, вы удваиваете одинарные кавычки. {"X": "Что за вопрос"} ==> {"X": "Что за вопрос"}

/codereview/69266/json-conversion-to-single-quotes

Последовательность неверна.

4T2G
источник
2
Удвоение одиночной кавычки в строке JSON не исключает ее. Это просто означает, что ваша строка содержит две одинарные кавычки вместо одной.
Марк Амери
-15

относительно сообщения AlexB:

 \'  Apostrophe or single quote
 \"  Double quote

экранирование одинарных кавычек допустимо только в строках json с
одинарными кавычками экранирование двойных кавычек допустимо только в строках json с двойными кавычками

пример:

'Bart\'s car'       -> valid
'Bart says \"Hi\"'  -> invalid
Барт
источник
14
Строки в одинарных кавычках недопустимы в JSON. JSON не является JavaScript. JSON не позволяет экранировать одинарную кавычку. Смотрите json.org для очень простого документа синтаксиса JSON.
ср
3
downvote - потому что одинарные кавычки jsons не действительны!
Доминик Анжерер
Одиночные кавычки недействительны в JSON. Пожалуйста, покажите рабочий образец, если это возможно
Рохит