JSON

JSON
Лого на JSON езика
Реализиране през2001
АвторДъглас Крокфорд
Софтуерен разработчикState Software
Повлиян отJavaScript
Уебсайтjson.org
JSON в Общомедия

JSON е съкращение от JavaScript Object Notation – текстово базиран отворен стандарт, създаден за човешки четим обмен на данни. Произлиза от скриптовия език JavaScript, за да представя прости структури от данни и асоциативни масиви, наречени обекти. Въпреки своята връзка с JavaScript, това е езиково независима спецификация, с анализатори, които могат да преобразуват много други езици в JSON.

Форматът на JSON първоначално е създаден от Дъглас Крокфорд (Douglas Crockford) и е описан в RFC 4627. Официалният интернет медия тип за JSON е application/json. Разширението на файловете написани на JSON е .json.

Форматът на JSON често е използван за сериализация и предаване на структурирани данни през интернет връзка. Използва се главно, за да предаде данни между сървър и интернет приложение, изпълнявайки функциите на алтернатива на XML.

Дъглас Крокфорд първи установява и популяризира JSON формата.[1]

JSON е бил използван в State Software Inc. – компания, основана през април 2001 г. и спонсорирана от Tesla Ventures. Един от основателите ѝ е Крокфорд. Когато компанията е създадена през ранната 2001 от шест бивши служители на Communities.com, те се съгласяват да създадат система, която да използва стандартните възможности на браузъра и да предоставят абстрактен слой на интернет разработчиците, за да създават динамично защитени интернет приложения, които да имат постоянна дуплекс връзка с интернет сървъра, която да държи две HTTP връзки отворени. Тя ги презарежда преди стандартните за браузъра времена за прекъсване, ако няма повече данни, които да се обменят. Идеята на State Application Framework е разработена от Чип Морнингстар (Chip Morningstar) в State Software.[2][3]

Използван е в проект на Communities.com за Cartoon Network, които използват плъгини със собствен формат на съобщенията, за да манипулират DHTML елементите (тази система е собственост на 3DO). По време на ранното откриване на възможностите на езика Ajax, digiGroups, Noosh и други използвали рамки, за да предават информация във визуалното поле на браузърите на потребителите, без да е нужно да се презарежда визуалният контекст на интернет приложението. Всъщност интернет приложенията използвали само стандартните HTTP, HTML и JavaScript способности на Netscape 4.0.5+ и IE 5+. След това Дъглас Крокфорд осъзнал, че JavaScript може да бъде използван като обектно-базиран формат за пращане на съобщения за такава система. Системата е продадена на Sun Microsystems, Amazon.com и EDS. Интернет сайтът на Json JSON.org е стартиран през 2002 г. През декември 2005 г. Yahoo! започват да предлагат някои от своите интернет услуги в JSON код.[4] Google започва да предлага JSON поддръжка за неговия GData интернет протокол през декември 2006 г.[5]

Въпреки че JSON е оригинално базиран на нестриктно подмножество на скриптовия език JavaScript (по-специално стандартът ECMA-262 3rd Edition—декември 1999 г.[6]) и често се използва с този език, той е езиково независима спецификация за формат на данни. Код за анализиране и генериране на данни за JSON имат голямо разнообразие от програмни езици. Сайтът на JSON предоставя разбираемо подреждане на съществуващите JSON библиотеки, организирани от езика.

Типове данни, синтаксис и примери

[редактиране | редактиране на кода]

Базовите типове данни на JSON са:

  • Number (число с плаваща запетая, double precision floating-point format в JavaScript)
  • String (низ от символи с Unicode кодиране, затворени в двойни кавички, като „специалните“ символи се представят с т.нар. escaping – символни последователности, започващи със символа „\“)
  • Boolean (true или false)
  • Array (наредена поредица от стойности, разделени със запетая и затворени в квадратни скоби; стойностите не е задължително да бъдат от един и същ тип)
  • Object (неподредена колекция от двойки ключ:стойност, символът „:“ разделя ключа и стойността, разделени със запетая и затворени в къдрави скоби; ключовете трябва да са стрингове и да са различни един от друг)
  • null (empty)

Всяко незначимо бяло пространство може да бъде добавено около „структурните символи“ (като скоби „{} []“, двоеточие ‘:’ и запетаи ‘,’).

Следващият пример показва представянето на обект, който описва човек в JSON. Обектът има string полета за първо и последно име, Number поле за години, Object, който представя адреса на човека, и Array от телефонни номера, представени като Object.

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": 10021
    },
    "phoneNumbers": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

Един потенциален недостатък на свободната форма на JSON идва от възможността числата да се пишат като числови константи или низове в кавички. Например ZIP кодовете в североизточна Америка започват с нули (например 07728 за Freehold, New Jersey). Ако числото е написано с кавички, започващите нули може да се пропуснат при обмяна на данни между системите, когато се търси за тях в същата система или когато се печатат. Като добавка пощенските кодове в САЩ използват числа, но в други страни използват и букви. Това е типът проблеми, с които JSON Schema-та (виж по-надолу) се цели да се справи.

Откакто JSON e почти подмножество на JavaScript е възможно, но не се препоръчва[7] да се преобразува текстът от JSON в обект, като се използва функцията на JavaScript eval(). Като пример, ако горните данни от JSON кода се поберат в JavaScript string променлива contact, може да се използва, за да се създаде обект както следва:

 var p = eval("(" + contact + ")");

Променливата contact трябва да бъде в скоби, за да се избегне двусмислието в JavaScript синтаксиса.[8]

Предпочитаният начин обаче е да се използва JSON анализатор. Освен ако клиентът не вярва на източника или трябва да анализира и приеме текст, който не е JSON съвместим, човек трябва да избягва eval(). Коректно имплементран JSON анализатор приема само валиден JSON код, предотвратявайки изпълнение на злонамерени кодове по погрешка.

 var p = JSON.parse(contact);

Интернет браузърите, като Firefox и Internet Explorer, включват от 2010 специални функции, които да анализират JSON. Като поддръжката на браузъра е по-ефикасна и сигурна отколкото eval(). Поддръжката на JSON e включена в петото издание на ECMAScript стандарта.[9]

Библиотеките на jQuery обвиват обекта на JSON във функция конструктор и я изпълняват незабавно, ако не съществува JSON анализатор. Това избягва ползването на eval().

 var p = new Function('return ' + contact ';')();

Въпреки широко разпространеното вярване, че JSON e подмножество на JavaScript, това не е вярно. По-точно JSON позволява уникод прекъсващите реда символи U+2028 РЕД РАЗДЕЛИТЕЛ и U+2029 ПАРАГРАФ РАДЕЛИТЕЛ да изглеждат не избегнати поставени в кавички, докато Java Script не го прави. Това е вследствие на непозволяващите „контролни литерали“ в JSON. Тази фина разлика е важна, когато се генерира JASONP.

Неподдържани от JSON типове данни

[редактиране | редактиране на кода]

JavaScript синтаксисът дефинира няколко присъщи за него типове данни, които не са включени в стандарта на JSON.[10]

Date, Error, Regular Expression, and Function. Тези JavaScript типове данни трябва да бъдат представени като някой друг формат данни, тъй като програмите от двата края не се разбират как става преобразуването на данните между типовете. От 2011 има някои стандарти като например за преобразуването на Date в String, но не са универсално разпознати.[11][12] Други езици може да имат различен брой присъщи типове, които могат внимателно да бъдат използвани, за да се разреши проблемът с преобразуването между типовете данни.

JSON Schema[13] определя JSON базиран формат, който да дефинира структурата на JSON данните за валидиране, документация и контрол на взаимодействието. JSON Schema-та осигурява споразумение между данните на JSON и приложението, което иска да ги ползва и модифицира. JSON Schema е базирана на концепцията на XML Schema, RelaxNG, и Kwalify, но е и JSON базирана, за да може данните на JSON във формата на JSON Schema да бъдат използвани, за да се валидират данни от JSON. Същите сериализационни/десриализационни инструменти могат да бъдат използвани за схемата и данните.

JSON Schema е Internet Draft, на version 4.[14] Има няколко сериални валидатори, които са налични за различните програмни езици, всеки с различни нива на съответствие.[15]

Примерна JSON Schema:

{
    "name": "Product",
    "properties": {
        "id": {
            "type": "number",
            "description": "Product identifier",
            "required": true
        },
        "name": {
            "type": "string",
            "description": "Name of the product",
            "required": true
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "required": true
        },
        "tags": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
        "stock": {
            "type": "object",
            "properties": {
                "warehouse": {
                    "type": "number"
                },
                "retail": {
                    "type": "number"
                }
            }
        }
    }
}

JSON Schema-та отгоре може да се използва, за да се валидира кодът по-долу:

{
    "id": 1,
    "name": "Foo",
    "price": 123,
    "tags": [ "Bar", "Eek" ],
    "stock": {
        "warehouse": 300,
        "retail": 20
    }
}

Официалният MIME тип за JSON е „application/json“.[16]

JSON-RPC е RPC протокол, разработен на JSON, като заместител на XML-RPC или SOAP. Той е прост протокол, който дефинира само няколко типове данни и команди. JSON-RPC разрешава известия (информация, изпратена до сървъра, която не изисква отговор) и множество от повиквания да бъдат изпратени до сървъра, които могат да бъдат отговорени, без да бъдат поръчвани.

Пример за JSON-RPC 2.0 заявка и отговор, използвайки позиционни параметри:

-->{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}

JSON често се използва в програмирането на Ajax. Ajax е термин за способността на уеб страницата да изисква нови данни след като е заредила в уеб браузъра, обикновено в отговор на действията на потребителя на изобразената интернет страница. Като част от модела на Ajax, новата информация обикновено се включва в интерфейса на потребителя и се показва динамично още щом се получи от сървъра. Като пример за това на практика е, че, ако някой потребител пише в search box, скриптове от браузъра на клиента изпращат какво е написал потребителят дотогава в сървъра, който отговаря с лист от възможни завършени търсения от неговата база данни. Те могат да бъдат изобразени като падащо меню под търсачката, за да може потребителят отгоре да спре да пише и да избере цялостен и често търсен низ директно. Когато е бил описан през средата на 2000-ната година, Ajax най-често използвал XML като формат за обмен на данни, но много разработчици също използвали JSON, за да предават обновления между сървъра и клиента.[17]

Следващият JavaScript код е пример за client, който използва XMLHttpRequest, за да изискат информацията в JSON формат от сървъра. (Програмирането от страна на сървъра е пропуснато; то трябва да е настроено да отговаря на заявките на url с JSON-форматиран string.)

var my_JSON_object;
var http_request = new XMLHttpRequest();
http_request.open("GET", url, true);
http_request.onreadystatechange = function () {
    var done = 4, ok = 200;
    if (http_request.readyState == done && http_request.status == ok) {
        my_JSON_object = JSON.parse(http_request.responseText);
    }
};
http_request.send(null);

Проблеми със сигурността

[редактиране | редактиране на кода]

Въпреки че JSON e предназначен като формат за сериализация на информация, неговият дизайн на ненизово подмножество на скриптовия език JavaScript има и няколко проблеми със сигурността. Тези проблеми изхождат от използването на JavaScript като интерпретатор, който да изпълнява JSON текст динамично като JavaScript. Ето защо излагането на програма, написана на JSON на скрипт, който е грешен или зловреден (скрит в кода), често представлява най-голям проблем за избягване, когато се справяте с получаване на информация от интернет. Въпреки че не е единственият начин за обработване на JSON, това е лесна и популярна техника, произхождаща от съвместимостта на JSON с JavaScript-овата функция eval() и илюстрирана от следващите примери.

Тъй като повечето от JSON форматираният текст е синтактично валиден JavaScript код, един лесен начин за JavaScript програмите да се преобразуват в JSON форматирана информация е да се използват вградената JavaScript eval() функция, която е предназначена да изпълнява JavaScript изрази. Вместо да се използва специален анализатор за JSON, интерпретаторът на JavaScript се използва, за да изпълнява информацията от кода на JSON и да произвежда нейтив JavaScript обекти. Въпреки това има няколко Unicode символа, които са валидни JSON низове, но невалидни в JavaScript. Ето защо още избягващи символи са нужни в някои ситуации преди използването на JavaScript интерпретатора.[18]

Освен ако не се вземат предпазни мерки и първо да се валидират данните, техниката на eval е предмет на уязвимост в сигурността, ако данните и цялата среда на JavaScript не са под контрола на една система, на която може да се разчита. Като пример, ако данните сами по себе си не са достоверни, то може да сте предмет на атака от зловреден JavaScript. Също такива пробиви в сигурността може да създадат предпоставки за кражба на данни, кражба на самоличност и други потенциални грешни употреби на данни и ресурси. Регулярни изрази могат да бъдат използвани, за да се валидират правата на данните, които извикват eval(). Като пример RFC, който дефинира JSON(RFC 4627), предполага използването на код за валидиране на JSON преди да се извика eval() (променливата 'text' е входът на JSON):

var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
    text.replace(/"(\\.|[^"\\])*"/g, ''))) && eval('(' + text + ')');

Нова функция JSON.parse() е разработена като по-сигурна алтернатива на eval. Тя е специално предназначена да обработва JSON код, а не JavaScript. Първоначално е планувано да се включи в четвъртото издание на ECMAScript стандарта,[19] но това не се случило. За първи път е било добавено към петото издание,[20] и се поддържа от повечето браузъри, които са дадени по-надолу. За по-старите има съвместима JavaScript библиотека, която е налична на JSON.org.

Нейтив кодиране и декодиране в браузъри

[редактиране | редактиране на кода]

Скорошните интернет браузъри или имат или разработват нейтив JSON кодиране/ декодиране. Това не само елиминира проблема в сигурността с използването на eval(), но също така увеличава производителността, защото вече функциите не трябва да се преобразуват. Нейтив JSON е по-бърз в сравнение с JavaScript библиотеките често използвани преди. От юни 2009 следващите браузъри имат нейтив поддръжка на JSON с JSON.parse() и JSON.stringify():

Най-малко пет популярни JavaScript библиотеки използват JSON, ако е възможно:

Кодирането по подразбиране в JSON e UTF8; той също поддържа UTF16 и UTF32.

Станадартът на JSON не поддържа обекти, но Dojo Toolkit илюстрира как спогодбите могат да бъдат осиновени, за да поддържат такива референции, използвайки стандартен JSON. Специален dojox.json.ref модул дава поддръжка за няколко форми на получаване включително circular, множествени, inter-message, и lazy съотнасяния.[30][31] Алтернативни нестандартни решения съществуват, като използването на Mozilla JavaScript Sharp Variables, въпреки че тази функционалност е премахната от Firefox във version 12.[32]

Сравнение с други формати

[редактиране | редактиране на кода]

JSON е промотиран като слаба алтернатива на XML като и двата от тези формати имат голяма подкрепа за създаване, четене и декодиране в ситуации от реалния живот, където те често се използват.[33] Освен XML, примерите могат да включват OGDL, YAML и CSV. Също Google Protocol Buffers могат да изпълнят тази роля, въпреки че не е език за обмен на данни.

YAML е почти, но не напълно, подмножество на JSON. Като пример, избягването на наклонената черта (/) става с обратно наклонена черта (\) и е валиден JSON, но не и YAML. (Това е честа практика, когато се имплементира JSON в HTML, за да се защита от скриптови атаки от други сайтове.) Въпреки че, много YAML анализатори могат да анализират директно изхода на много JSON енкодери.[34]

XML е бил използван за да се описват структури от данни и да се сериализират обекти. Съществуват различни XML-базирани портоколи, които да представят същият тип от структури от данни като JSON код за размяна на същите типове данни. Когато данни са кодирани в XML, резултатът обикновено е по-голям от колкото еквивалентното му кодиране в JSON, главно заради затварящите тагове на XML. Ако данните са компресирани използвайки алгоритъм като gzip има много малка разлика, защото компресията е добра в пестенето на място, когато даден код се повтаря на няколко места.

XML стойностите нямат специфичен тип данни.

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": "10021"
    },
    "phoneNumber": [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

И двата следващи примера имат един и същ тип от информация като JSON примера отгоре, но записано по различни начини.

Горният JSON код е също 100% валиден YAML; YAML също предлага алтернативен синтаксис, предназначен да бъде по-човешки достъпен като замества наследените разделители като {}, [] и " със структурирани бели пространства, които подреждат кода чрез вдлъбвания.[34]

---
  firstName:  John
  lastName:  Smith
  age: 25
  address:
        streetAddress: 21 2nd Street
        city: New York
        state: NY
        postalCode: 10021

  phoneNumber:
        -
            type: home
            number: 212 555-1234
        -
            type: fax
            number: 646 555-4567
<person>
  <firstName>John</firstName>
  <lastName>Smith</lastName>
  <age>25</age>
  <address>
    <streetAddress>21 2nd Street</streetAddress>
    <city>New York</city>
    <state>NY</state>
    <postalCode>10021</postalCode>
  </address>
  <phoneNumbers>
    <phoneNumber type="home">212 555-1234</phoneNumber>
    <phoneNumber type="fax">646 555-4567</phoneNumber>
  </phoneNumbers>
</person>
<person firstName="John" lastName="Smith" age="25">
  <address streetAddress="21 2nd Street" city="New York" state="NY" postalCode="10021" />
  <phoneNumbers>
     <phoneNumber type="home" number="212 555-1234"/>
     <phoneNumber type="fax"  number="646 555-4567"/>
  </phoneNumbers>
</person>

Ето защо XML кодиранетоможеда бъде сравнено по дължина с еквивалентно JSON кодиране. Съществуват много XML обработващи технологии, от Document Object Model до XPath и XSLT. XML също може да бъде стилизирано за мигновено показване, използвайки CSS. XHTML е форма на XML, в която елементите могат да бъдат подавани готови за директно имплементиране в интернет страници, използвайки скриптове от страна на клиента.

  • S-expression – сравнителният LISP за дървета като текст.
  • JSONP – JSON с Padding, модел на използване на често заемани, когато се извлича JSON код от домейни
  • BSON – бинарен JSON
  • GeoJSON – отворен формат за кодиране на различни географски структури от данни
  • JSON-LD – JavaScript Object Notation за свързани данни, за момента е W3C Working Draft
  • JSON-RPC
  • SOAPjr – хибрид от SOAP и JR (JSON-RPC)
  • JsonML
  • Jayrock – отворен код за имплементация на JSON за .NET Framework
  1. Video: Douglas Crockford – The JSON Saga Архив на оригинала от 2011-05-11 в Wayback Machine., on Yahoo! Developer Network. In the video Crockford states: „I do not claim to have invented JSON ... What I did was I found it, I named it, I described how it was useful. ... So, the idea's been around there for a while. What I did was I gave it a specification, and a little Web site.“
  2. Chip Morningstar Biography // undated.
  3. State Software Breaks Through Web App Development Barrier With State Application Framework: Software Lets Developers Create Truly Interactive Applications; Reduces Costs, Development Time and Improves User Experience // PR Newswire. 12 февруари 2002.
  4. Yahoo!. Using JSON with Yahoo! Web services // Архивиран от оригинала на 2007-10-11. Посетен на 3 юли 2009.
  5. Google. Using JSON with Google Data APIs // Посетен на 3 юли 2009.
  6. Crockford, Douglas. Introducing JSON // json.org, 28 май 2009. Посетен на 3 юли 2009.
  7. JSON in JavaScript Архив на оригинала от 2016-07-10 в Wayback Machine., on JSON's web page: "The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues [...]"
  8. Crockford, Douglas. JSON in JavaScript // json.org, 9 юли 2008. Архивиран от оригинала на 2016-07-10. Посетен на 8 септември 2008.
  9. Standard ECMA-262
  10. RFC 4627
  11. jquery – How to format a JSON date? – Stack Overflow
  12. Dates and JSON – Tales from the Evil Empire
  13. JSON Schema
  14. JSON Schema draft 4
  15. JSON Schema реализации
  16. IANA | Application Media Types
  17. Garrett, Jesse James. Ajax: A New Approach to Web Applications // Adaptive Path, 18 февруари 2005. Посетен на 19 март 2012.
  18. JSON: The JavaScript subset that isn't // Magnus Holm. Архивиран от оригинала на 2012-05-13. Посетен на 16 май 2011.
  19. Crockford, Douglas. JSON: The Fat-Free Alternative to XML // 6 декември 2006. Посетен на 3 юли 2009.
  20. ECMAScript Fifth Edition // Посетен на 18 март 2011.
  21. Using Native JSON // 30 юни 2009. Архивиран от оригинала на 2012-03-05. Посетен на 3 юли 2009.
  22. Barsan, Corneliu. Native JSON in IE8 // 10 септември 2008. Посетен на 3 юли 2009.
  23. Web specifications supported in Opera Presto 2.5 // 10 март 2010. Посетен на 29 март 2010.
  24. Hunt, Oliver. Implement ES 3.1 JSON object // 22 юни 2009. Посетен на 3 юли 2009.
  25. YUI 2: JSON utility // 1 септември 2009. Архивиран от оригинала на 2012-01-14. Посетен на 22 октомври 2009.
  26. Learn JSON // 7 април 2010. Посетен на 7 април 2010.
  27. Ticket #4429 // 22 май 2009. Архивиран от оригинала на 2012-02-20. Посетен на 3 юли 2009.
  28. Ticket #8111 // 15 юни 2009. Архивиран от оригинала на 2012-02-20. Посетен на 3 юли 2009.
  29. Ticket 419 // 11 октомври 2008. Посетен на 3 юли 2009.
  30. Zyp, Kris. JSON съотнасяния към Dojo // Юли 17, 2008. Посетен на Юли 3, 2009.
  31. von Gaza, Tys. JSON referencing in jQuery // Dec 7, 2010. Архивиран от оригинала на 2011-10-05. Посетен на Dec 7, 2010.
  32. Sharp променливи JavaScript // Архивиран от оригинала на 2012-05-06. Посетен на 21 април 2012.
  33. JSON: Алтернативата на XML // json.org. Посетен на 14 март 2011.
  34. а б YAML Version 1.2