JSON (, в английском обычно произносится как или ) — текстовый формат обмена данными, основанный на JavaScript. Как и многие другие текстовые форматы, JSON легко читается людьми. Формат JSON был разработан Дугласом Крокфордом.

Несмотря на происхождение от JavaScript (точнее, от подмножества языка стандарта ECMA-262 1999 года), формат считается независимым от языка и может использоваться практически с любым языком программирования. Для многих языков существует готовый код для создания и обработки данных в формате JSON.

Передаваемый текст должен быть в кодировке UTF-8 без BOM.

Использование За счёт своей лаконичности по сравнению с XML формат JSON может быть более подходящим для сериализации сложных структур. Применяется в веб-приложениях как для обмена данными между браузером и сервером (AJAX), так и между серверами (программные HTTP-сопряжения).

Поскольку формат JSON является подмножеством синтаксиса языка JavaScript, то он может быть быстро десериализован встроенной функцией JSON.parse().

Синтаксис JSON-текст представляет собой (в закодированном виде) одну из двух структур: Набор пар ключ: значение. В различных языках это реализовано как запись, структура, словарь, хеш-таблица, список с ключом или ассоциативный массив. Ключом может быть только строка (регистрозависимость не регулируется стандартом, это остаётся на усмотрение программного обеспечения. Как правило, регистр учитывается программами — имена с буквами в разных регистрах считаются разными, например), значением — любая форма. Повторяющиеся имена ключей допустимы, но не рекомендуются стандартом; обработка таких ситуаций происходит на усмотрение программного обеспечения, возможные варианты — учитывать только первый такой ключ, учитывать только последний такой ключ, генерировать ошибку. Упорядоченный набор значений. Во многих языках это реализовано как массив, вектор, список или последовательность.

Структуры данных, используемые JSON, поддерживаются любым современным языком программирования, что и позволяет применять JSON для обмена данными между различными языками программирования и программными системами.

В качестве значений в JSON могут быть использованы: запись — это неупорядоченное множество пар ключ:значение, заключённое в фигурные скобки «{ }». Ключ описывается строкой, между ним и значением стоит символ «:». Пары ключ-значение отделяются друг от друга запятыми. массив (одномерный) — это упорядоченное множество значений. Массив заключается в квадратные скобки «[ ]». Значения разделяются запятыми. Массив может быть пустым, то есть не содержать ни одного значения. Значения в пределах одного массива могут иметь разный тип. число (целое или вещественное). литералы true (логическое значение «истина»), false (логическое значение «ложь») и null. строка — это упорядоченное множество из нуля или более символов юникода, заключённое в двойные кавычки. Символы могут быть указаны с использованием escape-последовательностей, начинающихся с обратной косой черты «\» (поддерживаются варианты \", \\, \/, \t, \n, \r, \f и \b), или записаны шестнадцатеричным кодом в кодировке Unicode в виде \uFFFF.

Строка очень похожа на литерал одноимённого типа данных в языке JavaScript. Число тоже очень похоже на JavaScript-число, за исключением того, что используется только десятичный формат (с точкой в качестве разделителя). Пробелы могут быть вставлены между любыми двумя синтаксическими элементами.

Следующий пример показывает JSON-представление данных об объекте, описывающем человека. В данных присутствуют строковые поля имени и фамилии, информация об адресе и массив, содержащий список телефонов. Как видно из примера, значение может представлять собой вложенную структуру.

{ "firstName": "Иван", "lastName": "Иванов", "address": { "streetAddress": "Московское ш., 101, кв.101", "city": "Ленинград", "postalCode": 101101 }, "phoneNumbers": [ "812 123-1234", "916 123-4567" ] }

В качестве значений в JSON могут быть использованы как числа, так и строки. Поэтому запись "postalCode": "101101" содержит строку, а "postalCode": 101101 — уже числовое значение. Из-за слабой типизации в JavaScript и PHP строка может быть приведена к числу и не влиять на логику программы. Тем не менее, рекомендуется аккуратно обращаться с типом значения, так как JSON служит для межсистемного обмена.

На языке XML подобная структура выглядела бы примерно так:

<person> <firstName>Иван</firstName> <lastName>Иванов</lastName> <address> <streetAddress>Московское ш., 101, кв.101</streetAddress> <city>Ленинград</city> <postalCode>101101</postalCode> </address> <phoneNumbers> <phoneNumber>812 123-1234</phoneNumber> <phoneNumber>916 123-4567</phoneNumber> </phoneNumbers> </person>

или так:

<person firstName="Иван" lastName="Иванов"> <address streetAddress="Московское ш., 101, кв.101" city="Ленинград" postalCode="101101" /> <phoneNumbers> <phoneNumber value="812 123-1234"/> <phoneNumber value="916 123-4567"/> </phoneNumbers> </person>

JSON5 JSON5 — предложенное расширение формата json в соответствии с синтаксисом ECMAScript 5, вызванное тем, что json используется не только для общения между программами, но и создаётся/редактируется вручную. Файл JSON5 всегда является корректным кодом ECMAScript 5. JSON5 обратно совместим с JSON. Для некоторых языков программирования уже существуют парсеры json5.

Некоторые нововведения: Поддерживаются как однострочные //, так и многострочные /* */ комментарии. Записи и списки могут иметь запятую после последнего элемента (удобно при копировании элементов). Ключи записей могут быть без кавычек, если они являются валидными идентификаторами ECMAScript 5. Строки могут заключаться как в одинарные, так и в двойные кавычки. Числа могут быть в шестнадцатеричном виде, начинаться или заканчиваться десятичной точкой, включать Infinity, -Infinity, NaN и -NaN, начинаться со знака +.

Сравнение с YAML Как функционально, так и синтаксически JSON является подмножеством языка YAML. В частности, спецификация YAML 1.2 указывает, что «любой файл в формате JSON является корректным файлом в формате YAML». Наиболее распространённый парсер YAML способен обрабатывать и JSON.. Спецификация YAML до версии 1.2 не полностью покрывала JSON, в первую очередь из-за отсутствия родной поддержки UTF-32 в YAML, а также требования пробела после разделителя-запятой; кроме того, спецификация JSON включала комментарии в стиле /* */.

Наиболее важным отличием YAML является набор расширений синтаксиса, которым нет аналогов в JSON: поддержка реляционных данных: в YAML-документе можно ссылаться на якорь, встретившийся ранее в файле/потоке; таким образом можно выразить рекурсивные структуры. поддержка расширяемых типов данных помимо примитивов: строк, чисел, логических значений и т. д. поддержка блочного синтаксиса с отступами; он позволяет описать структурированные данные без использования лишних символов: всевозможных скобок, кавычек и т. д.

JSON Schema JSON Schema — один из языков описания структуры JSON-документа. Использует синтаксис JSON. Базируется на концепциях XML Schema, RelaxNG, Kwalify. JSON Schema — самоописательный язык: при его использовании для обработки данных и описания их допустимости могут использоваться одни и те же инструменты сериализации/десериализации.

Формат JSON-LD для связанных данных

Стандарт JSON не поддерживает ссылки на объекты, но желаемого результата можно достичь при помощи дополнительных соглашений. Рекомендацией W3C для связанных данных является JSON-LD, в котором использована модель данных RDF. В JSON-LD к данным добавляется контекст (context), связывающий свойства объектов JSON-документа с элементами онтологий.

Использование JSON в Ajax Следующий пример Javascript-кода показывает, как браузер может использовать XMLHttpRequest, чтобы запрашивать с сервера объект в формате JSON (серверная часть программы опущена; в ней должен быть размещён код, отправляющий данные в формате JSON-строки в ответ на запросы по url).

var http_request = new XMLHttpRequest(); http_request.onreadystatechange = function () { if (http_request.readyState !== 4) return;

if (http_request.status !== 200) throw new Error('request was defeated');

do_something_with_object(JSON.parse(http_request.responseText)); http_request = null; }; http_request.open("GET", url, true); http_request.send(null);

Заметим, что данный пример применения XMLHttpRequest не поддерживает Internet Explorer до версии 6 включительно, так что для них следует использовать несколько иной код. Возможности применения XMLHttpRequest ограничены из-за правила ограничения домена (same origin policy): URL-ответ на запрос должен находиться в том же DNS-домене, что и сервер, на котором находится страница, запрашивающая ответ. В качестве альтернативы применяется подход JSONP, включающий в себя использование закодированного вызова функции, передающегося между клиентом и сервером, чтобы клиент мог загружать закодированные в JSON данные со сторонних доменов, и уведомлять о завершении вызывающую сторону, хотя это приводит к некоторым рискам для безопасности и дополнительным требованиям к серверу.

Как вариант, в коде страницы можно использовать элементы <iframe> для асинхронного запроса JSON-данных, или просто <form action="url_to_cgi_script">. Эти подходы были распространены до появления широкой поддержки XMLHttpRequest.

Также можно использовать для передачи JSON-данных динамические теги <script>. С помощью этого метода можно обойти правило ограничения домена (same origin policy), но он приводит к появлению уязвимого кода. В качестве более безопасной альтернативы было предложено использовать JSONRequest.

Вопросы безопасности Хотя JSON предназначен для передачи данных в сериализованном виде, его синтаксис соответствует синтаксису JavaScript и это создаёт ряд проблем безопасности. Зачастую для обработки данных, полученных от внешнего источника в формате JSON, к ним применяется функция eval() без какой-либо предварительной проверки.

JavaScript eval() Поскольку JSON представляется синтаксически правильным фрагментом кода JavaScript, простейшим способом разбора JSON-данных в JavaScript-программе является использование встроенной в JavaScript функции eval(), которая предназначена для выполнения JavaScript-выражений. При этом подходе отпадает необходимость в использовании дополнительных парсеров.

Техника использования eval() делает систему уязвимой, если источник используемых JSON-данных не является . В качестве таких данных может выступать вредоносный JavaScript код для атак класса . С помощью данной уязвимости возможно осуществлять кражу данных, подделку аутентификации.

Была предложена новая функция JSON.parse(), способная обрабатывать только JSON-данные. Она была представлена в четвёртой версии стандарта ECMAScript и описана в статье «JSON: Обезжиренная альтернатива XML». В настоящее время она доступна как библиотека JavaScript и была включена в пятую редакцию ECMAScript.

Встроенный JSON Последние версии веб-браузеров имеют встроенную поддержку JSON и способны его обрабатывать.

Подделка кроссдоменного запроса

Непродуманное использование JSON делает сайты уязвимыми для подделки межсайтовых запросов (CSRF или XSRF). Поскольку тег <script> допускает использование источника, не принадлежащего к тому же домену, что и использующий ресурс, это позволяет выполнять код под видом данных, представленных в формате JSON, в контексте произвольной страницы, что делает возможным компрометацию паролей или другой конфиденциальной информации пользователей, прошедших авторизацию на другом сайте.