Формат JSON (от англ. JavaScript Object Notation) — это текстовый формат для передачи данных. Т.е. JSON произошел из JavaScript, но он также часто используется для передачи данных в языках Python, Ruby, PHP и Java, т.к. многие среды программирования имеют возможность читать (анализировать) и генерировать JSON.
Формат JSON подразумевает, что вы можете хранить данные в нем в файлах с расширением .json
. Кроме того, он может существовать в других форматах файлов, например, в .html
или .js
, но в них вы должны использовать JSON в виде строки, т.е. текста в кавычках. Также JSON может быть объектом, присвоенным в переменную. Такой формат легко передавать между сервером и клиентской частью, т.е. с помощью браузера.
В последнее время JSON постепенно вытесняет формат XML за счет того, что он легко читаем, компактен и требует куда меньше усилий для форматирования контента. Здесь мы рассмотрим, как можно использовать JSON, узнаем о его синтаксисе и методах для работы с этим форматом.
Синтаксис и структура
Объект JSON предполагает, что данные передаются в виде пар ключ-значение, заключенных в фигурные скобки. Например:
1 2 3 4 5 | { "companyName": "Арт-гостиная", "birthday": "20.05.2016", "city": "Киев", "address": "ул. Жилянская, 20" } |
Итак, формат JSON предполагает, что вы указываете сначала две фигурные скобки { }
, внутри которых записываете данные в формате ключ-значние. Ключ - это всегда строка в двойных (!и только в двойных) кавычках, а значение - либо тоже строка в двойных кавычках, либо число, либо логическое true|false
, либо null
, либо массив.
Когда вы создаёте ключи, лучше всего использовать строку с латинскими символами без пробелов, можно в Camel-синтаксисе или с нижним подчеркиванием, например: "companyName", "company_name", но не "company name".
Особенности JSON
- JSON - это формат данных - он содержит только свойства, а не методы.
- JSON в обязательном порядке требует двойных кавычек, которые будут использоваться вокруг строк и имен свойств. Одиночные кавычки недействительны.
- Можно легко допустить шибки в JSON, т.к. даже одна лишняя или забытая запятая или двоеточие может привести к сбою JSON-файла, в результате чего весь ваш код перестанет работать. Имеет смысл проверять JSON с помощью приложения, такого как JSONLint.
- JSON позволяет работать со строками, числами, булевыми величинами,
null
, массивами или объектами. Причем строки записываются в двойных кавычках, а числа,true|false
иnull
- без.
Для того чтобы проще было работать с JSON, можно установить дополнительные расширения для вашего редактора кода. Например, плагин JSON snippets для Visual Studio Code позволяет преобразовывать данные в строки в процессе набора текста.
В том числе с его помощью можно создавать данные в формате json в различных языках программирования (JavaScript, TypeScript и т.д.):
Методы JavaScript для работы с JSON
JavaScript предоставляет методы для работы JSON-форматом:
JSON.stringify()
для преобразования объектов в JSON.JSON.parse()
для преобразования JSON обратно в объект.
Метод JSON.stringify()
Первый метод JSON.stringify()
мы используем для преобразования данных в различных JavaScript-форматах в строку, которая будет отвечать синтаксису JSON.
Например,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | let animals = [{ name: "Mikky", type: 'dog', age: 3, stock: { price: 13.9, isSold: true, acsessories: ['ball'] } }, { name: "Neon", type: 'cat', age: .5, stock: { price: 59.7, isSold: false, acsessories: null } }]; document.write('<p>' + JSON.stringify(animals) + '</p>'); |
Все пары ключ-значение теперь имеют обрамление в виде двойных кавычек, массивы остались массивами, числовые значения, значение true
, false
и null
остались без изменения.
Это простой способ использования метода JSON.stringify()
. Но у него есть еще 2 необязательных параметра:
1 | JSON.stringify(value[, replacer[, space]]) |
Параметр replacer
метода JSON.stringify()
Параметр replacer
подразумевает использование функции или массива свойств для кодирования, который будет выбран из всех переданных значений. Например, если нет необходимости передавать или публиковать часть данных:
1 2 3 4 5 6 7 8 9 | var info = { companyName: "Арт-гостиная", birthday: "20.05.2016", city: "Киев", address: "ул. Жилянская, 20", numberOfEmployees: 72, vacancy: ['дизайнер','уборщица','кладовщик'] }; console.log( JSON.stringify(info, ['companyName', 'city','address']) ); |
Результат работы параметра replacer
в виде массива (для вывода console.log
заменен на document.write
):
Использование функции function(key, value)
в параметре replacer подразумевает, что мы перебираем все свойства объекта по ключу (key
) или значению (value
) в соответствии с неким условием и оставляем только те свойства, которые этому условию удовлетворяют. Например, нам нужно отсортировать фамилии только с положительным дебетом
1 2 3 4 5 6 7 8 | let debet = [{ 'Иванов': 500 }, {'Петров': -169 }, {'Пупкин': 1270 }, { 'Васильева': -740 }, { 'Гущин': -200 }]; console.log( JSON.stringify(debet, function(key, value) { if (value < 0) { return undefined; } return value; }) ); |
Результат - 2 из 5 элементов массива:
Параметр space
метода JSON.stringify()
Третий необязательный параметр метода JSON.stringify()
называется space
и указывает количество пробелов (отступов) для красивого форматирования строки в JSON-формате. Для передачи данных это необязательно, для вывода информации - будет смотреться красиво. В качестве значения параметра space можно использовать целое число или знак табуляции.
1 2 3 4 5 6 7 8 9 10 11 12 | let address = { country: "USA", details: { state: 'California', city: 'Los Angeles', zipCode: 90001 } }; console.log("2 пробела: " + JSON.stringify(address, null, 2)); console.log("6 пробелов: " + JSON.stringify(address, null, 6)); console.log("Символ табуляции: " + JSON.stringify(address, null, "\t")); |
Можем посмотреть в консоли на разницу в форматировании:
Метод JSON.parse()
Метод JSON.parse()
, напротив, предназначен для преобразования данных из строки в объект JavaScript.
Например, у нас есть json-файл с данными о работниках некоей фирмы (все совпадения имен-фамилий - случайны, это выдуманная фирма с выдуманными сотрудниками, email-ами и телефонами), которые необходимо вывести в виде таблицы. Содержимое JSON-файла выглядит так (кстати, очень пригодился JSONLint, т.к. при форматировании было допущено несколько ошибок):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | { "companyName": "Арт-гостиная", "birthday": "20.05.2016", "city": "Киев", "address": "ул. Жилянская, 20", "workers": [{ "name": "Григорий Голобородько", "email": "goloborodko1978@gmail.com", "phone": "378-19-47", "position": "Директор", "active": "пн., ср. ,пт. 15-17-00" }, { "name": "Иван Мунич", "email": "munich-i@ukr.net", "phone": "378-19-48", "position": "Зам. директора", "active": "пн., ср. ,пт.14-17-00" }, { "name": "Ирина Белоголовко", "email": "belogolovko.irina@bigmir.net", "phone": "378-22-40", "position": "Главный бухгалтер", "active": "вт., ср. 14-17-00" }, { "name": "Степан Ефремов", "email": "efrem.st@yahoo.com", "phone": "378-12-32", "position": "Aрт-директор", "active": "вт., ср. 10-13-00" } ] } |
То есть в начале файла идёт информация о самой фирме, а затем - данные о сотрудниках в виде массива. Этот файл для начала необходимо загрузить, а затем распределить данные в div
и таблицу. Для этого в html-файле создадим простую разметку внутри body
:
1 2 | <div id="info"></div> <table id="workers"></table> |
Затем пишем скрипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | var workersTable = document.getElementById('workers'), info = document.getElementById('info'), requestURL = 'data.json', //файл находится в той же папке, что и html-файл, который к нему обращается request = new XMLHttpRequest(); request.open('GET', requestURL); request.onload = function(e) { if (request.readyState === 4) { if (request.status === 200) { console.log(request.response); var dataTable = JSON.parse(request.responseText); getTableInfo(dataTable); } else { console.error(request.statusText); } } }; request.onerror = function(e) { console.error(request.statusText); }; request.send(); function getTableInfo(data) { info.innerHTML = `<h2>Компания: ${data.companyName}</h2> <p>Адрес: ${data.city}, ${data.address}</p> <p>Дата основания: ${data.birthday}</p>`; let headerTr = document.createElement('tr'); headerTr.innerHTML = `<th>ФИО</th><th>Должность</th><th>Email</th> <th>Телефон</th><th>Приемные дни/часы</th>`; workersTable.appendChild(headerTr); // console.log(Array.isArray(data.workers)); data.workers.forEach(function(elem) { let tr = document.createElement('tr'); tr.innerHTML = `<td>${elem.name}</td><td>${elem.position}</td> <td>${elem.email}</td><td>${elem.phone}</td> <td>${elem.active}</td>`; workers.appendChild(tr); }); } |
В скрипте мы сначала получаем в ответе от сервера текстовые данные, которые записываем в переменную dataTable
с помощью метода JSON.parse()
:
1 | var dataTable = JSON.parse(request.responseText); |
А затем вызываем в функцию getTableInfo()
, которая делает разбор данных и добавляет их в div
и таблицу. Для разбора массива мы используем метод forEach()
, а перед этим убедимся, что после JSON.parse()
у нас остался именно массив:
1 | // console.log(Array.isArray(data.workers));//true |
Для добавления элементов мы воспользуемся методами document.createElement()
, appendChild()
и свойством innerHTML
.
1 2 3 4 | let tr = document.createElement('tr'); tr.innerHTML = `<td>${elem.name}</td><td>${elem.position}</td> <td>${elem.email}</td><td>${elem.phone}</td> <td>${elem.active}</td>`; workers.appendChild(tr); |
Обратите внимание на использование обратных кавычек и переменных вида ${var_name}
- это шаблонные литералы, добавленные в синтаксис стандарта ES6 , принесшего немало интересных фишек в JavaScript.
Сам пример вживую (открыть в новой вкладке):
Еще один пример загрузки JSON-файла вы найдете в статье с соответствующим названием "Использование AJAX для загрузки JSON-данных".
Параметр reviver
метода JSON.parse()
Как и JSON.stringify()
, метод JSON.parse()
может быть вызван со вторым необязательным параметром reviver
(см. документацию на MDN), который представляет собой вызов функции вида function(key, value)
, последовательно перебирающей все значения JSON-строки. В функции можно по какому-либо условию отсортировать значения ключей или сами ключи и вывести несколько измененный вариант JSON-данных. Важным моментом здесь является то, что функция в конце перебирает и всю строку, поэтому желательно в функции отслеживать ключ в виде пустой строки (key===''
) во избежание неприятностей:
1 2 3 4 5 6 7 8 | let strJson = '{"res1": 15, "res2": 48, "res3": 3,"fio": "Барабаш Сергей"}', parseWithFunc = JSON.parse(strJson, function(key, value) { console.log(key, key === 'fio', value) if (key === '') return value; if (typeof value === 'string') return value; //если значение - это строка, ничего с ней не делаем return value * 10 + ' баллов'; // иначе возвращаем value * 10. }); console.log('parseWithFunc = ', parseWithFunc) |
В данном примере нам необходимо было для вывода информации получить JSON-данные в виде неких баллов, полученных, например, при тестировании неким человеком, поэтому числовые значения мы умножали на 10 и добавляли к результату строку "баллов":
1 | return value * 10 + ' баллов' |
В результате получим в консоли следующий объект:
Получение данных JSON-файла с помощью jQuery
В jQuery есть специальный метод $.getJSON
, который позволяет простым способом получить информацию из внешнего источника, загрузив JSON-файл методом GET. Вы можете посмотреть пример загрузки файла с актуальными курсами валют с API Приватбанк в соответствующей статье.
Практика: отправка простой формы с помощью JSON
Рассмотрим вариант с отправкой данных в формате JSON из простой формы, в которой будет несколько полей и кнопка submit. В результате работы формы будет отправлено письмо на указанный в форме email. Поэтому имеет смысл указывать тот ящик, который вы сможете потом проверить. Отправлено письмо будет с помощью AJAX. Мы рассмотрим сначала вариант кода на чистом JavaScript.
Разметка формы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <form action="letter.php" name="simpleForm" id="simpleForm"> <p> <label for="first_name">Имя:</label> <input type="text" name="first_name" id="first_name" required> </p> <p> <label for="last_name">Фамилия:</label> <input type="text" name="last_name" id="last_name" required> </p> <p> <label for="phone">Телефон:</label> <input type="tel" name="phone" id="phone" required> </p> <p> <label for="to">Email:</label> <input type="email" name="to" id="to" required> </p> <input type="submit" id="submit" value="Отправить"> </form> <div id="sendMessage"></div> |
В html-коде нужно обратить внимание на атрибут action
тега <form>
и на отсутствие у кнопки submit
атрибута name
, т.к. они в дальнейшем повлияют на восприятие JS-кода. Также в самом низу присутствует пустой тег <div id="sendMessage"></div>
, в который затем мы будем выводить сообщение об отправке формы или об ошибке.
Код JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | var sendMessage = document.getElementById('sendMessage'); var form = document.getElementById('simpleForm'), url = form.action; form.onsubmit = function(e) { e.preventDefault(); var data = {}; //переменная для сбора данных из формы for (var i = 0, len = form.length; i < len; i++) { var input = form[i]; if (input.name) { data[input.name] = input.value; } } var jsonStr = JSON.stringify(data); //преобразуем данные из объекта data в json-строку console.log(data, jsonStr); var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); xhr.onreadystatechange = function() { if (xhr.readyState != 4) return; if (xhr.status != 200) { //alert(xhr.status + ': ' + xhr.statusText); sendMessage.innerHTML = xhr.statusText; //выводим сообщение об ошибке } else { console.log(xhr.response); //alert(xhr.responseText); //выводим полученное от PHP-скрипта сообщение об отправке письма sendMessage.innerHTML = xhr.responseText; form.reset();//очищаем форму } } xhr.send(jsonStr); //отсылаем строку в формате JSON } |
В этом скрипте мы собираем в переменную-объект data
данные в виде пар имя input = значение input
, причем только в том случае, если поле input
имеет атрибут name
. Этого атрибута не имеет только кнопка submit
, поэтому ее данные не войдут в объект data
и не будут отправлены на сервер. Для отправки мы преобразуем объект в строку в формате JSON и формируем AJAX-запрос и отправляем его на тот url
, который указан в атрибуте action
. В случае ошибки запроса выводим текст ошибки в <div id="sendMessage"></div>
, в случае успеха - выводим то сообщение, которое выдаст нам PHP-скрипт и очищаем форму.
Несколько строк с методом alert()
закомментированы. Вы можете убрать комментарии, чтобы посмотреть без консоли на данные в AJAX-запросе.
Код PHP
В php-файле мы декодируем формат JSON json_decode()
в переменную $data
а затем "разбираем" ее на отдельные переменные, причем их имена будут совпадать с именами input
-ов (атрибут name
). Затем эти переменные используем для формирования письма.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php $data = json_decode( file_get_contents("php://input") ); //print_r($data); foreach ($data as $key=>$value) { $$key = $value; } //$to .= ', address@gmail.com'; //Почта получателя, через запятую можно указать сколько угодно адресов $subject = 'Простая форма с отправкой данных на JSON'; //Заголовок сообщения $message = ' <html> <head> <title>'.$subject.'</title> </head> <body> <p>Имя: '.$first_name.' '.$last_name.'</p> <p>Телефон: '.$phone.'</p> </body> </html>'; //В тексте отправляемого сообщения можно использовать HTML теги $headers = "Content-type: text/html; charset=utf-8 \r\n"; //Кодировка письма $headers .= "From: простая форма на JSON <someaddress@your-domain.com>\r\n"; //Наименование и почта вашего сайта mail($to, $subject, $message, $headers); //Отправка письма с помощью php-функции mail echo "<p>Письмо отправлено. Спасибо.</p><p>Проверьте почту</p>"; ?> |
Смотрим пример в действии:
Если вы откроете пример в новой вкладке и перед тестированием запустите консоль, то увидите примерно следующее (в зависимости от того, как заполнили поля):
Практический пример: использование JSON для генерации случайной цитаты
В примере ниже вы не будете загружать файл формата JSON или отправлять данные. Вы используете этот формат для хранения массива цитат и выбираете одну из них, генерируя случайное число с помощью Math.random()
при клике на кнопку. Код простой, но, возможно, вы придумаете ему еще какое-то применение.
See the Pen JSON Random Quote Generator by Dudley Storey (@dudleystorey) on CodePen.
Как я вам благодарна!
После пары часов поиска, вы мое спасение!
Спасибо и вам, что оставили комментарий!
Первый из десятков перелопаченых сайт, на котором ТОЛКОВО и с нормальными (без дебильных
superheroes) примерами рассказано про json-файлы
Спасибо огромнейшее
Спасибо вам за ваш отзыв! Отлично, что статья вам помогла!
спасибо