JSON
| JSON | |
|---|---|
| Расширение | .json[1] |
| MIME-тип | application/json[2][3] |
| Тип формата | Обмен данными |
| Расширен из | JavaScript |
| Стандарт(ы) | RFC 8259 |
| Сайт | json.org (англ.) |
JSON (англ. JavaScript Object Notation, в английском обычно произносится как/ˈdʒeɪsən/[4]) —текстовый форматобмена данными, основанный наJavaScript. Как и многие другие текстовые форматы, JSON легко читается людьми. Формат JSON был разработанДугласом Крокфордом[5].
Несмотря на происхождение от JavaScript (точнее, от подмножества языка стандартаECMA-2621999 года), формат считается независимым от языка и может использоваться практически с любымязыком программирования. Для многих языков существует готовый код для создания и обработки данных в формате JSON.
Передаваемый текст должен быть в кодировкеUTF-8 безBOM[6].
Использование
[править |править код]За счёт своей лаконичности по сравнению сXML формат JSON может быть более подходящим длясериализации сложных структур.Применяется в веб-приложениях как для обмена данными междубраузером и сервером (AJAX), так и между серверами (программныеHTTP-сопряжения).
Поскольку формат JSON является подмножеством синтаксиса языка JavaScript, то он может быть быстро десериализован встроенной функциейJSON.parse().
Синтаксис
[править |править код]JSON-текст представляет собой (в закодированном виде) одну из двух структур:
- Набор парключ: значение. В различных языках это реализовано какзапись,структура,словарь,хеш-таблица,список с ключом илиассоциативный массив. Ключом может быть только строка (регистрозависимость не регулируется стандартом, это остаётся на усмотрение программного обеспечения. Как правило, регистр учитывается программами — имена с буквами в разных регистрах считаются разными, например[7]), значением — любая форма. Повторяющиеся имена ключей допустимы, но не рекомендуются стандартом; обработка таких ситуаций происходит на усмотрение программного обеспечения, возможные варианты — учитывать только первый такой ключ, учитывать только последний такой ключ, генерировать ошибку.
- Упорядоченный наборзначений. Во многих языках это реализовано какмассив,вектор, список илипоследовательность.
Структуры данных, используемые 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>812123-1234</phoneNumber><phoneNumber>916123-4567</phoneNumber></phoneNumbers></person>
или так:
<personfirstName="Иван"lastName="Иванов"><addressstreetAddress="Московское ш., 101, кв.101"city="Ленинград"postalCode="101101"/><phoneNumbers><phoneNumbervalue="812 123-1234"/><phoneNumbervalue="916 123-4567"/></phoneNumbers></person>
JSON5
[править |править код]JSON5 — предложенное расширение формата json в соответствии с синтаксисом ECMAScript 5, вызванное тем, что json используется не только для общения между программами, но и создаётся/редактируется вручную[8]. Файл JSON5 всегда является корректным кодомECMAScript 5. JSON5 обратно совместим с JSON. Для некоторых языков программирования уже существуют парсеры json5[9].
Некоторые нововведения:
- Поддерживаются как однострочные
//, так и многострочные/* */комментарии. - Записи и списки могут иметь запятую после последнего элемента (удобно при копировании элементов).
- Ключи записей могут быть без кавычек, если они являются валидными идентификаторами ECMAScript 5.
- Строки могут заключаться как в одинарные, так и в двойные кавычки.
- Числа могут быть в шестнадцатеричном виде, начинаться или заканчиваться десятичной точкой, включать Infinity, -Infinity, NaN и -NaN, начинаться со знака +.
Сравнение с YAML
[править |править код]Как функционально, так и синтаксически JSON является подмножеством языкаYAML. В частности, спецификация YAML 1.2 указывает, что «любой файл в формате JSON является корректным файлом в формате YAML»[10]. Наиболее распространённыйпарсер YAML способен обрабатывать и JSON[11]. Спецификация YAML до версии 1.2 не полностью покрывала JSON, в первую очередь из-за отсутствия родной поддержкиUTF-32 в YAML, а также требования пробела после разделителя-запятой; кроме того, спецификация JSON включала комментарии в стиле /* */.
Наиболее важным отличием YAML является набор расширений синтаксиса, которым нет аналогов в JSON:
- поддержкареляционных данных: в YAML-документе можно ссылаться на якорь, встретившийся ранее в файле/потоке; таким образом можно выразитьрекурсивные структуры.
- поддержкарасширяемых типов данных помимопримитивов: строк, чисел, логических значений и т. д.
- поддержкаблочного синтаксиса с отступами; он позволяет описатьструктурированные данные без использования лишних символов: всевозможных скобок, кавычек и т. д.
JSON Schema
[править |править код]JSON Schema — один из языков описания структуры JSON-документа. Использует синтаксис JSON. Базируется на концепцияхXML Schema,RelaxNG,Kwalify. JSON Schema — самоописательный язык: при его использовании для обработки данных и описания их допустимости могут использоваться одни и те же инструментысериализации/десериализации[12].
Формат JSON-LD для связанных данных
[править |править код]Стандарт JSON не поддерживаетссылки на объекты, но желаемого результата можно достичь при помощи дополнительных соглашений. РекомендациейW3C для связанных данных являетсяJSON-LD, в котором использована модель данныхRDF. В JSON-LD к данным добавляется контекст (context), связывающий свойства объектов JSON-документа сэлементами онтологий[13].
Использование JSON вAjax
[править |править код]Следующий пример Javascript-кода показывает, как браузер может использоватьXMLHttpRequest, чтобы запрашивать с сервера объект в формате JSON (серверная часть программы опущена; в ней должен быть размещён код, отправляющий данные в формате JSON-строки в ответ на запросы поurl).
varhttp_request=newXMLHttpRequest();http_request.onreadystatechange=function(){if(http_request.readyState!==4)return;if(http_request.status!==200)thrownewError('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() без какой-либо предварительной проверки.
JavaScripteval()
[править |править код]Поскольку JSON представляется синтаксически правильным фрагментом кода JavaScript, простейшим способом разбора JSON-данных в JavaScript-программе является использование встроенной в JavaScript функцииeval(), которая предназначена для выполнения JavaScript-выражений. При этом подходе отпадает необходимость в использовании дополнительных парсеров.
Техника использованияeval() делает систему уязвимой, если источник используемых JSON-данных не являетсядоверенным[англ.]. В качестве таких данных может выступать вредоносный JavaScript код для атак классаВнедрение кода[англ.]. С помощью данной уязвимости возможно осуществлять кражу данных, подделку аутентификации.
Была предложена новая функцияJSON.parse(), способная обрабатывать только JSON-данные. Она была представлена в четвёртой версии стандартаECMAScript и описана в статье «JSON: Обезжиренная альтернатива XML»[14]. В настоящее время она доступна какбиблиотека JavaScript[15] и была включена в пятую редакцию ECMAScript.
Встроенный JSON
[править |править код]Последние версии веб-браузеров имеют встроенную поддержку JSON и способны его обрабатывать.
Подделка кроссдоменного запроса
[править |править код]Непродуманное использование JSON делает сайты уязвимыми дляподделки межсайтовых запросов (CSRF или XSRF)[16]. Поскольку тег<script> допускает использование источника, не принадлежащего к тому же домену, что и использующий ресурс, это позволяет выполнять код под видом данных, представленных в формате JSON, в контексте произвольной страницы, что делает возможнымкомпрометацию паролей или другой конфиденциальной информации пользователей, прошедших авторизацию на другом сайте.
Это представляется проблемой только в случае содержания в JSON-данных конфиденциальной информации, которая может быть компрометирована третьей стороной и если сервер рассчитывает наполитику одного источника[англ.], блокируя доступ к данным при обнаружении внешнего запроса. Это не является проблемой, если сервер определяет допустимость запроса, предоставляя данные только в случае его корректности.HTTP cookie нельзя использовать для определения этого. Исключительное использование HTTP cookie используетсяподделкой межсайтовых запросов.
JSONP и JSONPP
[править |править код]JSONP (англ. JSON Padding — «JSON с подкладкой») является расширением JSON, когда имя функции обратного вызова указывается в качестве входного аргумента.
В основу технологии положен тот факт, что политика безопасности браузера не запрещает использовать тег<script type="text/javascript" src="…"></script> для обращения к серверам, отличным от сервера, с которого произошла загрузка страницы.
Без использования технологии JSONP (то есть используя просто JSON кодирование данных) сервер может вернуть только данные. Например, так:
{"paper":"A4","count":5}
Однако это только данные, и они не могут влиять на браузер.
Используя технику JSONP, стороннему серверу передаётся в строке вызова (GET) имя callback функции:
<script type="text/javascript" src="http://example.com/getjson?jsonp=parseResponse"></script>
Здесь параметр jsonp содержит имя callback функции parseResponse.
Теперь посторонний сервер example.com может вернуть следующий код:
parseResponse({"paper":"A4","count":5})
Теперь код вызывает javascript-функцию первого домена.
Первоначально идея была предложена в блоге MacPython в 2005 году[17] и в настоящее время используется многимиWeb 2.0 приложениями, такими, какDojo Toolkit Applications, Google Toolkit Applications [https://www.webcitation.org/6Djo88laj?url=http://www.gwtapps.com/?p=42%5d и zanox Web Services. Дальнейшие расширения этого протокола были предложены с учётом ввода дополнительных аргументов, как, например, в случае JSONPP[18] при поддержкеS3DB веб-сервисов.
Поскольку JSONP использует скрипт теги, вызовы по сути открыты миру. По этой причине JSONP может быть неуместными для хранения конфиденциальных данных[19].
Включение скриптовых тегов от удалённых сайтов позволяет им передать любой контент на сайте. Если удалённый сайт имеет уязвимости, которые позволяют выполнить Javascript инъекции, то исходный сайт также может быть затронут ими.
JSONPP (англ. parameterized JSON with padding — «параметризованный JSON с подкладкой») — развитие идеи JSONP.
JSONPP включает в себя URL источника, имя функции, которая будет обрабатывать JSON данные, строка для eval после получения данных и строка для eval после окончания обработки данных:
JSON_call(SRC,JSONP,JSONPP,ONLOAD);
в итоге оборачивается
ans=JSONP(SRC){eval(JSONPP(ans));eval(ONLOAD);}
Вообще, для самой идеи JSONPP не принципиально количество параметров. Достаточно SRC, JSONP, JSONPP (и их обработка на стороне сервера, а затем клиента) для того, чтобы это был JSONPP.
Рассмотрим на примере работы с сервисом S3DB.
functions3db_jsonpp_call(src,next_eval){varcall="call_"+Math.random().toString().replace(/\./g,"");varheadID=document.getElementsByTagName("head")[0];varscript=document.createElement('script');script.id=call;script.type='text/javascript';// using padded, parameterized jsonsrc=src+"&format=json&jsonp=s3db_jsonpp&jsonpp="+next_eval+"&onload=remove_element_by_id('"+script.id+"')";script.src=src;headID.appendChild(script);// retrieve answer}functions3db_jsonpp(ans,jsonpp){eval(jsonpp);returnans;}functionremove_element_by_id(id){vare=document.getElementById(id);e.parentNode.removeChild(e);returnfalse;}
В примере функцияs3db_jsonpp_call() создаёт в DOM в части head элемент script, src которого соответствует вызову JSONPP.
После получения ответа от сервера будет вызванаs3db_jsonpp() — она передана в параметрах вызова, как это должно быть по правилам JSONP.
Внутриs3db_jsonpp() сработаетeval(jsonpp), и произойдёт возврат значения ans.
Вызов eval(onload) приводит к выполнениюremove_element_by_id() с id созданного скрипта в head и в итоге к его удалению, ведь он уже всё равно не будет использоваться, поскольку id в примере было сгенерировано случайным образом в самом начале функцииs3db_jsonpp_call(). Этот вызов в ответе сервера.
JSONB
[править |править код]JSONB — бинарное расширение JSON, внедрённое в СУБДPostgreSQL в версии 9.4.18. Фактически, JSONB является бинарным представлением JSON[20], с тем различием, что в хранимых строках пробелы удаляются, сортировка объектов не сохраняется и сохраняется только последнее значение для ключей-дубликатов[21].
См. также
[править |править код]Примечания
[править |править код]- ↑https://www.file-extension.info/format/json
- ↑Crockford D.The application/json Media Type for JavaScript Object Notation (JSON) (англ.) —IETF, 2006. — 10 p. —doi:10.17487/RFC4627
- ↑https://www.iana.org/assignments/media-types/application/json
- ↑Doug Crockford "Google Tech Talks: #" (7 февраля 2009). Дата обращения: 28 сентября 2017. Архивировано 29 июля 2017 года.
- ↑JSON Redux AKA RFC7159 . Дата обращения: 12 сентября 2014. Архивировано 2 июля 2014 года.
- ↑RFC 8259, раздел 8.1 "String and Character Issues / Character Encoding" . Дата обращения: 10 апреля 2024. Архивировано 10 апреля 2024 года.
- ↑JSON-RPC 1.1 Alt: Service, Procedure and Parameter Names . Дата обращения: 28 апреля 2016. Архивировано 9 марта 2016 года.
- ↑JSON5 by aseemk . Дата обращения: 26 ноября 2015. Архивировано 11 декабря 2015 года.
- ↑In The Wild · json5/json5 Wiki · GitHub . Дата обращения: 27 января 2017. Архивировано 5 декабря 2020 года.
- ↑YAML Ain’t Markup Language (YAML™) Version 1.2 (англ.). — Working Draft 2008-05-11. Дата обращения: 24 сентября 2009. Архивировано 16 мая 2008 года.
- ↑YAML is JSON . RedHanded (7 апреля 2005). Дата обращения: 25 сентября 2012. Архивировано 7 декабря 2012 года..
- ↑Json.Com. JSON Schema Proposal (англ.). Архивировано изоригинала 14 мая 2008 года.
- ↑JSON-LD Syntax 1.0 (27 декабря 2011). Дата обращения: 30 декабря 2011. Архивировано 12 января 2012 года.
- ↑JSON: Обезжиренная альтернатива XML (англ.). Архивировано 12 февраля 2012 года.
- ↑json2.js (англ.). Дата обращения: 24 сентября 2009. Архивировано 12 февраля 2012 года.
- ↑Джереми Гроссмэн. Продвинутые техники атак на веб-приложения, использующие GMail (англ.). WhiteHat Security. Дата обращения: 23 сентября 2009. Архивировано 12 февраля 2012 года.
- ↑from __future__ import * » Remote JSON - JSONP . Bob.pythonmac.org. Дата обращения: 8 сентября 2008. Архивировано 12 февраля 2012 года.
- ↑Almeida, Jonas. JSON, JSONP, JSONPP?. — S3DB, 2008. — 11 июня. Архивировано 15 февраля 2017 года.
- ↑RIAspot. JSON P for Cross Site XHR . Архивировано 5 декабря 2008 года.
- ↑Когда использовать неструктурированные типы данных в PostgreSQL? Сравнение Hstore vs. JSON vs. JSONB. 29 июля 2016.Архивировано 4 июля 2018. Дата обращения: 4 июля 2018.
- ↑Чем PostgreSQL лучше других SQL баз данных с открытым исходным кодом. Часть 1. 29 апреля 2016.Архивировано 4 июля 2018. Дата обращения: 4 июля 2018.
Ссылки
[править |править код]- Страницы, использующие устаревший тег source
- Википедия:Cite web (не указан язык)
- Википедия:Cite web (заменить webcitation-архив: deadlink no)
- Википедия:Статьи с источниками из Викиданных
- ПРО:ИТ:Статьи по алфавиту
- ПРО:ИТ:Последняя правка: в текущем году
- Википедия:Статьи с разделами без ссылок на источники с мая 2018 года
- Википедия:Статьи без источников (тип: формат файла)
- Статьи с примерами кода JavaScript
- Страницы, использующие волшебные ссылки RFC