ДомойПолезноеФорматы хранения данных xml и json. Формат JSON: что это такое, как создать и открыть файл. Развитие и применение
Форматы хранения данных xml и json. Формат JSON: что это такое, как создать и открыть файл. Развитие и применение
JSON - это текстовый формат записи данных.
Он позволяет в текстовом виде представить как отдельное число или строку, так и сложные структуры, например, массивы с данными. Использование этого формата записи удобно тем, что он читабелен и интуитивно понятен, в то же время позволяет сохранять очень сложные структуры данных. Кроме того, он более компактный, чем xml, поэтому на мой взгляд более предпочтителен для обмена данными между веб-браузером и сервером.
Синтаксис JSON на примерах
Формат json обычно записывается в 2-х вариантах:
1. Последовательность значений. Например, последовательность 10, 15 и "test" в формате JSON будут выглядеть так:
В языке php начиная с версии 5.2. есть всего 4 функции:
json_decode
- Декодирует строку JSON (из строки json-формата получает данные)
json_encode
- Возвращает JSON-представление данных (преобразует данные в json-строку)
json_last_error_msg
- Возвращает строку с сообщением об ошибке последнего вызова json_encode() или json_decode()
json_last_error
- Возвращает последнюю ошибку
В основном по-большей части, используются всего две функции: json_encode
и json_decode
. Не буду вдаваться в подробности их синтаксиса, подробнее можете посмотреть на php.net . Пример использования:
Обратите внимание
: при кодировании в JSON-формат данных на русском языке
, функция json_encode преобразует русские символы в юникод
, т.е. заменяет их на \uXXXX
и таким образом, json-строка становится не читабельной для человека (но понятной для браузера). Если нужно, чтобы преобразования в юникод не происходило (например, при отладке кода), можно просто использовать опцию JSON_UNESCAPED_UNICODE.
Так же, чтобы при кодировании не добавлялись слэши для экранирования и чтобы строки с числами кодировались как числа, можно использовать JSON_UNESCAPED_SLASHES и JSON_NUMERIC_CHECK. В итоге, чтобы json-строка была читабельной для человека, сделаем, например, так:
Еще один момент: если нужно чтобы при декодировании json-строки функция json_decode возвращала именно массив
, просто добавьте второй параметр в функцию равный true.
Начнем с того, что JSON-формат, изначально был придуман для языка JavaScript и потом стал просто отдельным текстовым форматом, используемым в разных языках. Видимо, поэтому синтаксис JSON очень похож на синтаксис записи обычных объектов и массивов.
// Пример массива в JavaScript
arr = ;
alert(arr); // выведет 1
// Пример объекта в JavaScript
obj = {
"name": "Вася",
"age": 35,
"isAdmin": false
}
alert(obj.name); // выведет "Вася"
Функции JavaScript, используемые для преобразования в JSON-формат и обратно:
JSON.parse
- декодирование JSON-строки (преобразование строки в объекты и/или массивы)
JSON.stringify
- возвращает JSON-представление данных (преобразование объектов и/или массивов в json-строку)
Простой пример декодирования json-строки в массив с цифрами:
При сериализации (преобразовании) объекта в JSON-строку, вызывается метод toJSON
этого объекта, если он существует. Если метода нет, тогда перечисляются все свойства объекта. Пример преобразования объекта с методом toJSON:
Собственно, лично я, применяю формат JSON в 2-х основных ситуациях:
1. Передача данных между браузером и сервером с использованием Ajax-запросов.
Например, у нас есть какая-то страница, на которой нужно обновить данные без перезагрузки страницы. Допустим, нужно чтобы с сервера "подгрузилась" информация со списком сотрудников и их данными.
В JavaScript с помощью jQuery делаем простой и выводим данные в виде таблицы в браузер:
$.getJSON("get-info.php").success(function(data) { // ajax-запрос, данные с сервера запишутся в переменную data
htmlstr = "
Я специально не стал показывать строку в виде "дерева", т.к. она передается именно в таком виде. И как вы можете оценить, запись данных в формате JSON получилась очень компактной
, а это значит, что передача этих данных от сервера к браузеру будет практически мгновенной.
2. Запись сложных структур данных в базу данных.
Иногда бывают ситуации, когда заводить еще одну таблицу в базе данных не целесообразно, чтобы сохранить различные данные. Допустим, предположим, у зарегистрированного на сайте пользователя есть возможность сделать настройку цвета фона и цвета текста.
Вместо того, чтобы заводить еще одну таблицу ради 2-х настроек, можно просто в таблице со списком пользователей сделать текстовый столбец, в который помещать данные настроек пользователя. Тогда запрос обновления настроек, может например, быть таким:
UPDATE users SET settings = "{"background-color":"#FFFFFF", "text-color":"#000000"}" WHERE user_id = 10
В будущем, получив из таблицы users
информацию, скрипт php может легко превратить их обратно в массив с настройками. Например, если переменная $user_info содержит данные, полученные по пользователю из таблицы users, получить массив с настройками очень просто:
Таким образом, как видно из примеров, в формате JSON можно хранить и передавать практически любую информацию.
Наверняка вы когда-нибудь слышали о JSON. Что же это такое? Что он может и как его использовать?
В данном уроке мы расскажем об основах JSON и раскроем следующие пункты:
Что такое JSON?
Для чего используется JSON?
Как создать строку JSON?
Простой пример строки JSON.
Сравним JSON и XML.
Как работать с JSON в JavaScript и PHP?
Что такое JSON?
JSON - простой, основанный на использовании текста, способ хранить и передавать структурированные данные. С помощью простого синтаксиса вы можете легко хранить все, что угодно, начиная от одного числа до строк, массивов и объектов, в простом тексте. Также можно связывать между собой массивы и объекты, создавая сложные структуры данных.
После создания строки JSON, ее легко отправить другому приложению или в другое место сети, так как она представляет собой простой текст.
JSON имеет следующие преимущества:
Он компактен.
Его предложения легко читаются и составляются как человеком, так и компьютером.
Его легко преобразовать в структуру данных для большинства языков программирования (числа, строки, логические переменные, массивы и так далее)
Многие языки программирования имеют функции и библиотеки для чтения и создания структур JSON.
Название JSON означает JavaScript Object Notation (представление объектов JavaScript). Как и представляет имя, он основан на способе определения объектов (очень похоже на создание ассоциативных массивов в других языках) и массивов.
Для чего используется JSON?
Наиболее частое распространенное использование JSON - пересылка данных от сервера к браузеру. Обычно данные JSON доставляются с помощью AJAX , который позволяет обмениваться данными браузеру и серверу без необходимости перезагружать страницу.
Пользователь нажимает миниатюру продукта в онлайн магазине.
JavaScript, выполняющийся на браузере, генерирует запрос AJAX к скрипту PHP, запущенному на сервере, передавая ID выбранного продукта.
Скрипт PHP получает название продукта, описание, цену и другую информацию из базы данных. Затем составляет из данных строку JSON и отсылает ее браузеру.
JavaScript, выполняющийся на браузере, получает строку JSON, декодирует ее и выводит информацию о продукте на странице для пользователя.
Также можно использовать JSON для отправки данных от браузера на сервер, передавая строку JSON в качестве параметра запросов GET или POST. Но данный метод имеет меньшее распространение, так как передача данных через запросы AJAX может быть упрощена. Например, ID продукта может быть включен в адрес URL как часть запроса GET.
Библиотека jQuery имеет несколько методов, например, getJSON() и parseJSON() , которые упрощают получение данных с помощью JSON через запросы AJAX.
Как создать строку JSON?
Есть несколько основных правил для создания строки JSON:
Строка JSON содержит либо массив значений, либо объект (ассоциативный массив пар имя/значение).
Массив
заключается в квадратные скобки ([ и ]) и содержит разделенный запятой список значений.
Объект
заключается в фигурные скобки ({ и }) и содержит разделенный запятой список пар имя/значение.
Пара имя/значение
состоит из имени поля, заключенного в двойные кавычки, за которым следует двоеточие (:) и значение поля.
Значение
в массиве или объекте может быть:
Числом (целым или с плавающей точкой)
Строкой (в двойных кавычках)
Логическим значением (true или false)
Другим массивом (заключенным в квадратные скобки)
Другой объект (заключенный в фигурные скобки)
Значение null
Чтобы включить двойные кавычки в строку, нужно использовать обратную косую черту: \" . Так же, как и во многих языках программирования, можно помещать управляющие символы и шестнадцатеричные коды в строку, предваряя их обратной косой чертой. Смотрите детали на сайте JSON .
Простой пример строки JSON
Ниже приводится пример оформления заказа в формате JSON:
Мы создаем объект с помощью фигурных скобок ({ и }).
В объекте есть несколько пар имя/значение: "orderID": 12345 Свойство с именем "orderId" и целочисленным значением 12345 "shopperName": "Ваня Иванов" свойство с именем "shopperName" и строковым значением "Ваня Иванов" "shopperEmail": "[email protected]" Свойство с именем "shopperEmail" и строковым значением "[email protected]" "contents": [ ... ] Свойство с именем "contents" , значение которого является массивом "orderCompleted": true Свойство с именем "orderCompleted" и логическим значением true
В массиве "contents" есть 2 объекта, представляющие отдельные позиции в заказе. Каждый объект содержит 3 свойства: productID , productName , и quantity .
Кстати, так как JSON основан на объявлении объектов JavaScript, то вы можете быстро и просто сделать выше приведенную строку JSON объектом JavaScript:
Во многих отношениях вы можете рассматривать JSON как альтернативу XML, по крайней мере, в сфере веб приложений. Концепция AJAX оригинально основывалась на использовании XML для передачи данных между сервером и браузером. Но в последние годы JSON становится все более популярным для переноса данных AJAX.
Хотя XML является проверенной технологией, которая используется в достаточном количестве приложений, преимуществами JSON являются более компактный и простой для распознавания формат данных.
Вот как будет выглядеть выше приведенный пример объекта на XML:
Версия XML имеет существенно больший размер. В действительности она имеет длину 1128 символов, а вариант JSON - только 323 символа. Версию XML также достаточно трудно воспринимать.
Конечно, это радикальный пример. И возможно создать более компактную запись XML. Но даже она будет существенно длиннее эквивалента на JSON.
Работаем со строкой JSON в JavaScript
JSON имеет простой формат, но создавать строку JSON вручную достаточно утомительно. Кроме того, часто нужно взять строку JSON, конвертировать ее содержание в переменную, которую можно будет использовать в коде.
Большинство языков программирования имеют инструменты для простого преобразования переменных в строки JSON и наоборот.
Создаем строку JSON из переменной
JavaScript имеет встроенный метод JSON.stringify() , который берет переменную и возвращает строку JSON, представляющую ее содержание. Например, создадим объект JavaScript, который содержит сведения о заказе из нашего примера, а затем создадим из него строку JSON:
Обратите внимание, что метод JSON.stringify() возвращает строку JSON без пробелов. Ее сложнее читать, но зато она более компактна для передачи через сеть.
Существует несколько способов разобрать строку JSON в JavaScript, но самый безопасный и надежный - использовать встроенный метод JSON.parse() . Он получает строку JSON и возвращает объект или массив JavaScript, который содержит данные. Например:
Мы создали переменную jsonString , которая содержит строку JSON нашего примера с заказом. Затем мы передаем данную строку методу JSON.parse() , который создает объект, содержащий данные JSON и сохраняет его в переменной cart . Остается только осуществить проверку, выведя свойства объекта shopperEmail и productName массива contents .
В результате мы получим следующий вывод:
В реальном приложении ваш JavaScript код будет получать заказ в виде строки JSON в AJAX ответе от скрипта сервера, передавать строку методу JSON.parse() , а затем использовать данные для отображения на странице пользователя.
JSON.stringify() и JSON.parse() имеют другие возможности, такие как использование возвратных функций для пользовательской конвертации определённых данных. Такие опции очень удобны для конвертации различных данных в правильные объекты JavaScript.
Работаем со строкой JSON в PHP
PHP, как и JavaScript, имеет встроенные функции для работы с JSON строками.
Создаем строку JSON из переменной PHP
Функция json_encode() принимает переменную PHP и возвращает строку JSON, представляющую содержание переменной. Вот наш пример с заказом, написанный на PHP:
Данный код возвращает абсолютно такую же строку JSON, как и в примере с JavaScript:
В реальном приложении ваш скрипт PHP пришлет данную строку JSON как часть AJAX ответа браузеру, где JavaScript код с помощью метода JSON.parse() преобразует ее обратно в переменную для вывода на странице пользователя.
Вы может передавать различные флаги в качестве второго аргумента функции json_encode() . С их помощью можно изменять принципы кодирования содержания переменных в строку JSON.
Создаем переменную из строки JSON
Для преобразования строки JSON в переменную PHP используется метод json_decode() . Заменим наш пример для JavaScript с методом JSON.parse() на код PHP:
По умолчанию функция json_decode() возвращает объекты JSON как объекты PHP. Существуют обобщенные объекты PHP класса stdClass . Поэтому мы используем -> для доступа к свойствам объекта в примере выше.
Если вам нужен объект JSON в виде ассоциированного массива PHP, нужно передать true в качестве второго аргумента функции json_decode() . Например:
Также функции json_decode() можно передавать другие аргументы для указания глубины рекурсии и способов обработки больших целых чисел.
Заключение
Хотя JSON прост для понимания и использования, он является очень полезным и гибким инструментом для передачи данных между приложениями и компьютерами, особенно при использовании AJAX. Если вы планируете разрабатывать AJAX приложение, то нет сомнений, что JSON станет важнейшим инструментом в вашей мастерской.
Обозначение объектов JavaScript (JSON) - стандартный текстовый формат для представления структурированных данных на основе синтаксиса объекта JavaScript. Он обычно используется для передачи данных в веб-приложениях (например, отправка некоторых данных с сервера на клиент, поэтому их можно отображать на веб-странице или наоборот). Вы столкнетесь с этим довольно часто, поэтому в этой статье мы даем вам все, что вам нужно для работы с JSON, используя JavaScript, включая разбор JSON, чтобы вы могли получить доступ к данным внутри него и создавать JSON.
Нет, действительно, что такое JSON?
Мы собираемся загрузить его на нашу страницу и использовать некоторые изящные манипуляции DOM, чтобы отобразить их, например:
Получение JSON
Чтобы получить JSON, мы будем использовать API, называемый XMLHttpRequest (часто называемый XHR
). Это очень полезный объект JavaScript, который позволяет нам делать сетевые запросы для извлечения ресурсов с сервера через JavaScript (например, изображения, текст, JSON, даже фрагменты HTML), что означает, что мы можем обновлять небольшие разделы контента без необходимости перезагрузки всей страницы. Это привело к более отзывчивым веб-страницам и звучит захватывающе, но, к сожалению, выходит за рамки этой статьи, чтобы учить его гораздо более подробно.
Начнем с того, что мы собираемся сохранить URL-адрес JSON, который мы хотим получить в переменной. Добавьте нижеследующий код JavaScript:
var requestURL = "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json";
Чтобы создать запрос, нам нужно создать новый экземпляр объекта запроса из конструктора XMLHttpRequest , используя ключевое слово new . Добавьте следующую ниже свою последнюю строку:
var request = new XMLHttpRequest();
Теперь нам нужно открыть новый запрос, используя метод . Добавьте следующую строку:
request.open("GET", requestURL);
Это занимает не менее двух параметров - есть другие доступные параметры. Нам нужен только два обязательных для этого простого примера:
Метод HTTP, который следует использовать при выполнении сетевого запроса. В этом случае прекрасен, так как мы просто извлекаем некоторые простые данные.
URL-адрес для запроса - это URL-адрес файла JSON, который мы сохранили ранее.
Затем добавьте следующие две строки: здесь мы устанавливаем в JSON, так что XHR знает, что сервер будет возвращать JSON и что это должно быть преобразовано за кулисами в объект JavaScript. Затем мы отправляем запрос методом :
request.responseType = "json";
request.send();
Последний бит этого раздела предполагает ожидание ответа на возврат с сервера, а затем обращение с ним. Добавьте следующий код ниже вашего предыдущего кода:
request.onload = function() {
var superHeroes = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);
}
Здесь мы сохраняем ответ на наш запрос (доступный в свойстве ) в переменной superHeroes ; эта переменная теперь будет содержать объект JavaScript, основанный на JSON! Затем мы передаем этот объект двум вызовам функций - первый из них заполнит правильными данными, а второй создаст информационную карту для каждого героя в команде и вставляет ее в .
Мы завернули код в обработчике событий, который запускается, когда событие загрузки запускается в объекте запроса (см. ) - это связано с тем, что событие загрузки запускается, когда ответ успешно возвращается; делая это таким образом, гарантирует, что request.response определенно будет доступен, когда мы приступим, чтобы попытаться что-то с этим сделать.
Заполнение заголовка
Теперь мы извлекли данные JSON и превратили его в объект JavaScript, давайте воспользуемся им, написав две функции, на которые мы ссылались выше. Прежде всего, добавьте следующее определение функции ниже предыдущего кода:
Function populateHeader(jsonObj) {
var myH1 = document.createElement("h1");
myH1.textContent = jsonObj["squadName"];
header.appendChild(myH1);
var myPara = document.createElement("p");
myPara.textContent = "Hometown: " + jsonObj["homeTown"] + " // Formed: " + jsonObj["formed"];
header.appendChild(myPara);
}
Мы назвали параметр jsonObj , чтобы напомнить себе, что этот объект JavaScript возник из JSON. Здесь мы сначала создаем элемент с , устанавливаем его равным свойству squadName объекта, а затем добавляем его в заголовок с помощью . Затем мы выполняем очень похожую операцию с абзацем: создаем его, устанавливаем его текстовое содержимое и добавляем его в заголовок. Единственное различие заключается в том, что его текст задан как конкатенированная строка, содержащая как homeTown , так и formed свойства объекта.
Создание информационных карт героя
Затем добавьте следующую функцию внизу кода, которая создает и отображает карты супергероев:
Function showHeroes(jsonObj) {
var heroes = jsonObj["members"];
for (var i = 0; i < heroes.length; i++) {
var myArticle = document.createElement("article");
var myH2 = document.createElement("h2");
var myPara1 = document.createElement("p");
var myPara2 = document.createElement("p");
var myPara3 = document.createElement("p");
var myList = document.createElement("ul");
myH2.textContent = heroes[i].name;
myPara1.textContent = "Secret identity: " + heroes[i].secretIdentity;
myPara2.textContent = "Age: " + heroes[i].age;
myPara3.textContent = "Superpowers:";
var superPowers = heroes[i].powers;
for (var j = 0; j < superPowers.length; j++) {
var listItem = document.createElement("li");
listItem.textContent = superPowers[j];
myList.appendChild(listItem);
}
myArticle.appendChild(myH2);
myArticle.appendChild(myPara1);
myArticle.appendChild(myPara2);
myArticle.appendChild(myPara3);
myArticle.appendChild(myList);
section.appendChild(myArticle);
}
}
Для начала сохраним свойство members объекта JavaScript в новой переменной. Этот массив содержит несколько объектов, которые содержат информацию для каждого героя.
Затем мы используем для циклического прохождения каждого объекта в массиве. Для каждого из них мы:
Создаем несколько новых элементов: , , три
И
.
Установливаем , чтобы содержать name текущего героя.
Заполняем три абзаца своей secretIdentity , age и строкой, в которой говорится: «Суперспособности:», чтобы ввести информацию в список.
Сохраняем свойство powers в другой новой переменной под названием superPowers - это содержит массив, в котором перечислены сверхспособности текущего героя.
Используем другой цикл for , чтобы прокрутить сверхспособности текущего героя - для каждого из них мы создаем элемент
, помещаем в него сверхспособности, а затем помещаем listItem внутри элемента
(myList) с помощью appendChild() .
Последнее, что мы делаем, это добавить ,
И
внутри (myArticle), а затем добавляем в . Важное значение имеет порядок, в котором добавляются вещи, так как это порядок, который они будут отображать внутри HTML.
Примечание
. Если у вас возникли проблемы после нотации точек / скобок, которые мы используем для доступа к объекту JavaScript, это может помочь открыть файл superheroes.json на другой вкладке или в текстовом редакторе и обратиться к ней, когда вы смотрите на наш JavaScript. Вы также можете обратиться к нашей статье для получения дополнительной информации о нотации точек и скобок.
Преобразование между объектами и текстом
Вышеприведенный пример был прост с точки зрения доступа к объекту JavaScript, потому что мы задали XHR-запрос для прямого преобразования ответа JSON в объект JavaScript, используя.
), так и между самими серверами (программные HTTP-интерфейсы). Формат JSON также хорошо подходит для хранения сложных динамических структур в реляционных базах данных или файловом кэше.
Поскольку формат JSON является подмножеством синтаксиса языка JavaScript, то он может быть быстро десериализован встроенной функцией eval() . Кроме того, возможна вставка вполне работоспособных JavaScript-функций. В PHP, начиная с версии 5.2.0, поддержка JSON включена в ядро в виде функций json_decode() и json_encode() , которые сами преобразуют типы данных JSON в соответствующие типы PHP и наоборот.
Синтаксис
JSON строится на двух структурах:
Набор пар ключ/значение. В различных языках это реализовано как объект
, запись , структура , словарь , хэш-таблица , список с ключом или ассоциативный массив . Ключом может быть только строка, значением - любая форма.
Пронумерованный набор значений. Во многих языках это реализовано как массив
, вектор , список или последовательность .
Это - универсальные структуры данных. Теоретически, все современные языки программирования поддерживают их в той или иной форме. Так как JSON используется для обмена данными между различными языками программирования, то имеет смысл строить его на этих структурах.
В JSON используются их следующие формы:
Объект
- это неупорядоченное множество пар имя /значение , заключённое в фигурные скобки { }. Между именем и значением стоит символ ": "
, а пары имя/значение разделяются запятыми.
Массив
(одномерный) - это множество значений, имеющих порядковые номера (индексы). Массив заключается в квадратные скобки . Значения отделяются запятыми.
Значение
может быть строкой
в двойных кавычках, числом
, значением true
или false
, объектом
, массивом
, или значением null
. Эти структуры могут быть вложены друг в друга.
Строка
- это упорядоченное множество из нуля или более символов юникода , заключенное в двойные кавычки, с использованием escape-последовательностей начинающихся с обратной косой черты (backslash). Символы представляются простой строкой.
Имя
- это строка.
Строка
очень похожа на строку в языках и Java . Число
тоже очень похоже на С или Java-число, за исключением того, что используется только десятичный формат. Пробелы могут быть вставлены между любыми двумя символами.
Следующий пример показывает JSON-представление объекта, описывающего человека. В объекте есть строковые
поля имени и фамилии, объект, описывающий адрес, и массив, содержащий список телефонов.
На языке XML подобная структура выглядела бы примерно так:
Иван
Иванов
Московское ш., 101, кв.101
Ленинград
101101
812 123-1234
916 123-4567
812 123-1234
916 123-4567
Сравнение с YAML
Как функционально, так и синтаксически JSON является подмножеством языка YAML . В частности, спецификация YAML 1.2 указывает, что «любой файл в формате JSON является корректным файлом в формате YAML» . Наиболее распространённый парсер YAML способен обрабатывать и JSON . Спецификация YAML до версии 1.2 не полностью покрывала JSON, в первую очередь из-за отсутствия родной поддержки UTF-32 в YAML, а также требования пробела после разделителя-запятой. Кроме того, спецификация JSON включала комментарии в стиле /* */.
Наиболее важным отличием YAML является набор расширений синтаксиса, которым нет аналогов в JSON:
Реляционный:
YAML поддерживает реляционные данные: в YAML-документе можно ссылаться на якорь, встретившийся ранее в файле/потоке. Таким образом можно выразить рекурсивные структуры.
Расширяемый:
YAML поддерживает расширяемые типы данных помимо примитивов (то есть строк, чисел, логических значений).
Блоки:
в YAML доступен блочный синтаксис с отступами; он позволяет описать структурированные данные без использования лишних символов (всевозможных скобок, кавычек и т. д.).
JSON Schema
JSON Schema - один из языков описания структуры JSON документа. Использует синтаксис JSON. Базируется на концепциях XML Schema , RelaxNG, Kwalify. JSON Schema - самоописательный язык: при его использовании для обработки данных и описания их допустимости могут использоваться одни и те же инструменты сериализации /десериализации .
Использование JSON в Ajax
Следующий пример Javascript-кода показывает, как браузер может использовать XMLHttpRequest , чтобы запрашивать с сервера объект в формате JSON (cерверная часть программы опущена; в ней должен быть размещён код, отправляющий данные в формате JSON-строки в ответ на запросы по url).
Var
the_object;
var
http_request =
new
XMLHttpRequest()
;
http_request.open
( "GET"
,
url,
true
)
;
http_request.send
(null
)
;
http_request.onreadystatechange
=
function
()
{
if
( http_request.readyState
==
4
)
{
if
( http_request.status
==
200
)
{
the_object =
JSON.parse
(http_request.responseText
)
;
}
else
{
alert( "There was a problem with the URL."
)
;
}
http_request =
null
;
}
}
;
Заметим, что данный пример применения XMLHttpRequest не является универсальным для всех браузеров (для браузеров, основанных на Internet Explorer , Opera , Safari и Mozilla , в коде должны быть те или иные отличия). Возможности применения XMLHttpRequest ограничены из-за правила ограничения домена (same origin policy): URL ответа на запрос должен находиться в том же DNS домене, что и сервер, на котором находится страница, запрашивающая ответ. В качестве альтернативы применяется подход JSONP , включающий в себя использование закодированного вызова функции, передающегося между клиентом и сервером, чтобы клиент мог загружать закодированные в JSON данные со сторонних доменов, и уведомлять о завершении вызывающую сторону, хотя это приводит к некоторым рискам для безопасности и дополнительным требованиям к серверу.
Как вариант, в коде страницы можно использовать элементы для асинхронного запроса JSON данных, или просто . Эти подходы были распространены до появления широкой поддержки XMLHttpRequest.
Также можно использовать для передачи JSON-данных динамические теги правило ограничения домена (same origin policy), но он приводит к появлению уязвимого кода. В качестве более безопасной альтернативы было предложено использовать JSONRequest .
Вопросы безопасности
Хотя JSON предназначен для передачи данных в сериализованном виде, его синтаксис соответствует синтаксису JavaScript и это создает ряд проблем безопасности. Зачастую для обработки данных, полученных от внешнего источника в формате JSON, к ним применяется функция eval() без какой-либо предварительной проверки.
JavaScript eval()
Поскольку JSON представляется синтаксически правильным фрагментом кода JavaScript, простейшим способом разбора JSON-данных в JavaScript-программе является использование встроенной в JavaScript функции eval() , которая предназначена для выполнения JavaScript-выражений. При этом подходе отпадает необходимость в использовании дополнительных парсеров.
Техника использования eval() делает систему уязвимой, если источник используемых JSON-данных не является доверенным (англ.
). В качестве таких данных может выступать вредоносный JavaScript код для атак класса Внедрение кода (англ.
). С помощью данной уязвимости возможно осуществлять кражу данных, подделку аутентификации. Тем не менее, уязвимость можно устранить за счёт использования дополнительных средств проверки данных на корректность. Например, до выполнения eval() полученные от внешнего источника данные могут проверяться с помощью регулярных выражений . В RFC , определяющей JSON , предлагается использовать следующий код для проверки его соответствия формату JSON
Как более безопасная альтернатива eval() была предложена новая функция parseJSON(), способная обрабатывать только JSON-данные. Она была представлена в четвёртой версии стандарта ECMAScript и описана в статье «JSON: Обезжиренная альтернатива XML» . В настоящее время она доступна как библиотека JavaScript и будет включена в пятую редакцию ECMAScript.
Встроенный JSON
Последние версии веб-браузеров имеют встроенную поддержку JSON и способны его обрабатывать без вызова функции eval() , приводящей к описанной проблеме. Обработка JSON в таком случае обычно осуществляется быстрее. Так в июне 2009 года следующие браузеры имели встроенную поддержку JSON:
По крайней мере пять популярных библиотек JavaScript используют встроенный JSON в случае его доступности:
Подделка кроссдоменного запроса
Непродуманное использование JSON делает сайты уязвимыми к подделке межсайтовых запросов (CSRF или XSRF) . Поскольку тег допускает использование источника, не принадлежащего к тому же домену, что и использующий ресурс, это позволяет выполнять код под видом данных, представленных в формате JSON, в контексте произвольной страницы, что делает возможным компрометацию паролей или другой конфиденциальной информации пользователей, прошедших авторизацию на другом сайте.
Это представляется проблемой только в случае содержания в JSON-данных конфиденциальной информации, которая может быть компрометирована третьей стороной и если сервер рассчитывает на политику одного источника (англ.
), блокируя доступ к данным при обнаружении внешнего запроса. Это не является проблемой, если сервер определяет допустимость запроса, предоставляя данные только в случае его корректности. HTTP cookie нельзя использовать для определения этого. Исключительное использование HTTP cookie используется подделкой межсайтовых запросов .
JSONP & JSONPP
JSONP
(JSON Padding) или «JSON с подкладкой» является расширением JSON, когда имя функции обратного вызова указывается в качестве входного аргумента.
В основу технологии положен тот факт, что политика безопасности браузера разрешает использовать тег для обращения к серверам отличным от сервера с которого произошла загрузка страницы.
Без использования технологии JSONP (то есть используя просто JSON кодирование данных) сервер может вернуть только данные. Например так:
{
"paper"
:
"A4"
,
"count"
:
5
}
Однако это только данные и они не могут влиять на браузер.
Используя технику JSONP, стороннему серверу передается в строке вызова (GET) имя callback функции:
Здесь параметр jsonp содержит имя callback функции parseResponse.
Теперь посторонний сервер example.com может вернуть следующий код:
ParseResponse({
"paper"
:
"A4"
,
"count"
:
5
}
)
Теперь код вызывает javascript-функцию первого домена.
Первоначально идея была предложена в блоге MacPython в 2005 м году , и в настоящее время используется многими Web 2.0 приложениями, такими, как Dojo Toolkit Applications, Google Toolkit Applications и zanox Web Services. Дальнейшие расширения этого протокола были предложены с учетом ввода дополнительных аргументов, как, например, в случае JSONPP при поддержке S3DB веб-сервисов.
Поскольку JSONP использует скрипт теги, вызовы по сути открыты миру. По этой причине, JSONP может быть неуместными для хранения конфиденциальных данных .
Включение скриптовых тегов от удаленных сайтов позволяет им передать любой контент на сайте. Если удаленный сайт имеет уязвимости, которые позволяют выполнить 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.
Function
s3db_jsonpp_call(src,
next_eval)
{
var
call =
"call_"
+
Math
.random
()
.toString
()
.replace
(/\./g
,
""
)
;
var
headID =
document.getElementsByTagName
("head"
)
[
0
]
;
var
script =
document.createElement
("script"
)
;
script.id
=
call;
script.type
=
"text/javascript"
;
// using padded, parameterized json
src =
src+
"&format=json&jsonp=s3db_jsonpp&jsonpp="
+
next_eval+
"&onload=remove_element_by_id(""
+
script.id
+
"")"
;
script.src
=
src;
headID.appendChild
(script)
;
// retrieve answer
}
function
s3db_jsonpp(ans,
jsonpp)
{
eval(jsonpp)
;
return
ans;
}
function
remove_element_by_id(id)
{
var
e =
document.getElementById
(id)
;
e.parentNode
.removeChild
(e)
;
return
false
;
}
В примере функция 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(). Этот вызов в ответе сервера.
Ссылки на объекты
Стандарт JSON не поддерживает ссылки на объекты, однако, Dojo Toolkit демонстрирует, как при помощи дополнительных соглашений можно обеспечить поддержку таких ссылок средствами стандартного JSON. В частности, модуль dojox.json.ref предоставляет поддержку нескольких форм ссылок, включая круговые, множественные, междокументные и «ленивые » ссылки .
См. также
Примечания
YAML Ain’t Markup Language (YAML™) Version 1.2 (англ.)
. - Working Draft 2008-05-11.(недоступная ссылка - история
)
Проверено 24 сентября 2009.
. RedHanded (07 апреля 2005). Проверено 25 сентября 2012.
.
Json.Com
JSON Schema Proposal (англ.)
.(недоступная ссылка - история
)
RFC 4627
JSON: Обезжиренная альтернатива XML (англ.)
. Архивировано
json2.js (англ.)
. Архивировано из первоисточника 12 февраля 2012. Проверено 24 сентября 2009.
Использование встроенного JSON (англ.)
.
Встроенный JSON в IE8 (англ.)
. Архивировано из первоисточника 12 февраля 2012.
Web спецификации, поддерживаемые в Opera Presto 2.5 (англ.)
(March 10, 2010). Архивировано из первоисточника 12 февраля 2012. Проверено 29 марта 2010.
Реализация ES 3.1 объекта JSON (англ.)
.
Ticket #4429lang=en . Архивировано из первоисточника 12 февраля 2012.
Ticket #4429 (May 22, 2009). Архивировано из первоисточника 12 февраля 2012. Проверено 3 июля 2009.
Ticket #8111lang=en . Архивировано из первоисточника 12 февраля 2012.
MooTools Core & More 1.3.1 . Архивировано из первоисточника 12 февраля 2012.
YUI 2: JSON utility (September 1, 2009). Архивировано из первоисточника 12 февраля 2012. Проверено 22 октября 2009.
Learn JSON (April 7, 2010). Архивировано из первоисточника 12 февраля 2012. Проверено 7 апреля 2010.
Джереми Гроссмэн
Продвинутые техники атак на веб-приложения, использующие GMail (англ.)
. WhiteHat Security. Архивировано из первоисточника 12 февраля 2012. Проверено 23 сентября 2009.
from __future__ import * » Remote JSON - JSONP . Bob.pythonmac.org. Архивировано из первоисточника 12 февраля 2012. Проверено 8 сентября 2008.
RIAspot
JSON P for Cross Site XHR .(недоступная ссылка - история
)
JSON referencing in Dojo . Архивировано из первоисточника 12 февраля 2012.
Ссылки
Официальная домашняя страница формата на русском языке
json.js , json2.js - библиотека, разработанная Дугласом Крокфордом, для работы с данными JSON в JavaScript. Расширяет объект Object методом toJSONString, который затем присутствует в любом объекте, и осуществляет его преобразование в строку формата JSON.
json-rpc.org (англ.)
Языки разметки документов
Офисных документов
Compound Document Format ·
OOXML (SpreadsheetML, PresentationML, WordprocessingML) ·
Наверняка вы когда-нибудь слышали о JSON. Что же это такое? Что он может и как его использовать?
В данном уроке мы расскажем об основах JSON и раскроем следующие пункты:
Что такое JSON?
Для чего используется JSON?
Как создать строку JSON?
Простой пример строки JSON.
Сравним JSON и XML.
Как работать с JSON в JavaScript и PHP?
Что такое JSON?
JSON - простой, основанный на использовании текста, способ хранить и передавать структурированные данные. С помощью простого синтаксиса вы можете легко хранить все, что угодно, начиная от одного числа до строк, массивов и объектов, в простом тексте. Также можно связывать между собой массивы и объекты, создавая сложные структуры данных.
После создания строки JSON, ее легко отправить другому приложению или в другое место сети, так как она представляет собой простой текст.
JSON имеет следующие преимущества:
Он компактен.
Его предложения легко читаются и составляются как человеком, так и компьютером.
Его легко преобразовать в структуру данных для большинства языков программирования (числа, строки, логические переменные, массивы и так далее)
Многие языки программирования имеют функции и библиотеки для чтения и создания структур JSON.
Название JSON означает JavaScript Object Notation (представление объектов JavaScript). Как и представляет имя, он основан на способе определения объектов (очень похоже на создание ассоциативных массивов в других языках) и массивов.
Для чего используется JSON?
Наиболее частое распространенное использование JSON - пересылка данных от сервера к браузеру. Обычно данные JSON доставляются с помощью AJAX , который позволяет обмениваться данными браузеру и серверу без необходимости перезагружать страницу.
Пользователь нажимает миниатюру продукта в онлайн магазине.
JavaScript, выполняющийся на браузере, генерирует запрос AJAX к скрипту PHP, запущенному на сервере, передавая ID выбранного продукта.
Скрипт PHP получает название продукта, описание, цену и другую информацию из базы данных. Затем составляет из данных строку JSON и отсылает ее браузеру.
JavaScript, выполняющийся на браузере, получает строку JSON, декодирует ее и выводит информацию о продукте на странице для пользователя.
Также можно использовать JSON для отправки данных от браузера на сервер, передавая строку JSON в качестве параметра запросов GET или POST. Но данный метод имеет меньшее распространение, так как передача данных через запросы AJAX может быть упрощена. Например, ID продукта может быть включен в адрес URL как часть запроса GET.
Библиотека jQuery имеет несколько методов, например, getJSON() и parseJSON() , которые упрощают получение данных с помощью JSON через запросы AJAX.
Как создать строку JSON?
Есть несколько основных правил для создания строки JSON:
Строка JSON содержит либо массив значений, либо объект (ассоциативный массив пар имя/значение).
Массив
заключается в квадратные скобки ([ и ]) и содержит разделенный запятой список значений.
Объект
заключается в фигурные скобки ({ и }) и содержит разделенный запятой список пар имя/значение.
Пара имя/значение
состоит из имени поля, заключенного в двойные кавычки, за которым следует двоеточие (:) и значение поля.
Значение
в массиве или объекте может быть:
Числом (целым или с плавающей точкой)
Строкой (в двойных кавычках)
Логическим значением (true или false)
Другим массивом (заключенным в квадратные скобки)
Другой объект (заключенный в фигурные скобки)
Значение null
Чтобы включить двойные кавычки в строку, нужно использовать обратную косую черту: \" . Так же, как и во многих языках программирования, можно помещать управляющие символы и шестнадцатеричные коды в строку, предваряя их обратной косой чертой. Смотрите детали на сайте JSON .
Простой пример строки JSON
Ниже приводится пример оформления заказа в формате JSON:
Мы создаем объект с помощью фигурных скобок ({ и }).
В объекте есть несколько пар имя/значение: "orderID": 12345 Свойство с именем "orderId" и целочисленным значением 12345 "shopperName": "Ваня Иванов" свойство с именем "shopperName" и строковым значением "Ваня Иванов" "shopperEmail": "[email protected]" Свойство с именем "shopperEmail" и строковым значением "[email protected]" "contents": [ ... ] Свойство с именем "contents" , значение которого является массивом "orderCompleted": true Свойство с именем "orderCompleted" и логическим значением true
В массиве "contents" есть 2 объекта, представляющие отдельные позиции в заказе. Каждый объект содержит 3 свойства: productID , productName , и quantity .
Кстати, так как JSON основан на объявлении объектов JavaScript, то вы можете быстро и просто сделать выше приведенную строку JSON объектом JavaScript:
Во многих отношениях вы можете рассматривать JSON как альтернативу XML, по крайней мере, в сфере веб приложений. Концепция AJAX оригинально основывалась на использовании XML для передачи данных между сервером и браузером. Но в последние годы JSON становится все более популярным для переноса данных AJAX.
Хотя XML является проверенной технологией, которая используется в достаточном количестве приложений, преимуществами JSON являются более компактный и простой для распознавания формат данных.
Вот как будет выглядеть выше приведенный пример объекта на XML:
Версия XML имеет существенно больший размер. В действительности она имеет длину 1128 символов, а вариант JSON - только 323 символа. Версию XML также достаточно трудно воспринимать.
Конечно, это радикальный пример. И возможно создать более компактную запись XML. Но даже она будет существенно длиннее эквивалента на JSON.
Работаем со строкой JSON в JavaScript
JSON имеет простой формат, но создавать строку JSON вручную достаточно утомительно. Кроме того, часто нужно взять строку JSON, конвертировать ее содержание в переменную, которую можно будет использовать в коде.
Большинство языков программирования имеют инструменты для простого преобразования переменных в строки JSON и наоборот.
Создаем строку JSON из переменной
JavaScript имеет встроенный метод JSON.stringify() , который берет переменную и возвращает строку JSON, представляющую ее содержание. Например, создадим объект JavaScript, который содержит сведения о заказе из нашего примера, а затем создадим из него строку JSON:
Обратите внимание, что метод JSON.stringify() возвращает строку JSON без пробелов. Ее сложнее читать, но зато она более компактна для передачи через сеть.
Существует несколько способов разобрать строку JSON в JavaScript, но самый безопасный и надежный - использовать встроенный метод JSON.parse() . Он получает строку JSON и возвращает объект или массив JavaScript, который содержит данные. Например:
Мы создали переменную jsonString , которая содержит строку JSON нашего примера с заказом. Затем мы передаем данную строку методу JSON.parse() , который создает объект, содержащий данные JSON и сохраняет его в переменной cart . Остается только осуществить проверку, выведя свойства объекта shopperEmail и productName массива contents .
В результате мы получим следующий вывод:
В реальном приложении ваш JavaScript код будет получать заказ в виде строки JSON в AJAX ответе от скрипта сервера, передавать строку методу JSON.parse() , а затем использовать данные для отображения на странице пользователя.
JSON.stringify() и JSON.parse() имеют другие возможности, такие как использование возвратных функций для пользовательской конвертации определённых данных. Такие опции очень удобны для конвертации различных данных в правильные объекты JavaScript.
Работаем со строкой JSON в PHP
PHP, как и JavaScript, имеет встроенные функции для работы с JSON строками.
Создаем строку JSON из переменной PHP
Функция json_encode() принимает переменную PHP и возвращает строку JSON, представляющую содержание переменной. Вот наш пример с заказом, написанный на PHP:
Данный код возвращает абсолютно такую же строку JSON, как и в примере с JavaScript:
В реальном приложении ваш скрипт PHP пришлет данную строку JSON как часть AJAX ответа браузеру, где JavaScript код с помощью метода JSON.parse() преобразует ее обратно в переменную для вывода на странице пользователя.
Вы может передавать различные флаги в качестве второго аргумента функции json_encode() . С их помощью можно изменять принципы кодирования содержания переменных в строку JSON.
Создаем переменную из строки JSON
Для преобразования строки JSON в переменную PHP используется метод json_decode() . Заменим наш пример для JavaScript с методом JSON.parse() на код PHP:
По умолчанию функция json_decode() возвращает объекты JSON как объекты PHP. Существуют обобщенные объекты PHP класса stdClass . Поэтому мы используем -> для доступа к свойствам объекта в примере выше.
Если вам нужен объект JSON в виде ассоциированного массива PHP, нужно передать true в качестве второго аргумента функции json_decode() . Например:
Также функции json_decode() можно передавать другие аргументы для указания глубины рекурсии и способов обработки больших целых чисел.
Заключение
Хотя JSON прост для понимания и использования, он является очень полезным и гибким инструментом для передачи данных между приложениями и компьютерами, особенно при использовании AJAX. Если вы планируете разрабатывать AJAX приложение, то нет сомнений, что JSON станет важнейшим инструментом в вашей мастерской.