JavaScript Object Notation (JSON) – это стандартный текстовый формат представления структурированных данных, основанный на JavaScript. Он широко используется для передачи данных в веб-приложениях (например, для передачи некоторых данных с сервера клиенту и наоборот).
Друзья, поддержите нас вступлением в наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.
Вы будете сталкиваться с ним довольно часто, поэтому в этой статье мы дадим вам все необходимое для работы с JSON с помощью JavaScript, включая парсинг JSON для доступа к данным, а также создание файла JSON.
Необходимые знания: | Базовое понимание HTML и CSS, знакомство с основами JavaScript и OOJS (Object Oriented JavaScript). |
Цель: | Понять, как работать с данными, хранящимися в формате JSON, и создавать собственные объекты JSON. |
Нет, правда, что такое JSON?
JSON – это текстовый формат данных, который стал популярным благодаря Дугласу Крокфорду. Несмотря на то, что он очень похож на синтаксис объектов в JavaScript, его можно использовать независимо от JavaScript.
JSON существует в виде строки – это удобно при передаче данных по сети. Для доступа к данным его необходимо преобразовать в объект JavaScript. Это не является проблемой, поскольку JavaScript предоставляет глобальный объект JSON, который имеет методы для преобразования данных между этими двумя форматами.
Структура JSON
Как было описано выше, JSON представляет собой строку, формат которой очень похож на формат объекта в JavaScript. В JSON можно включать те же базовые типы данных, что и в стандартный объект JavaScript, – строки, числа, массивы, булевы и другие объектные литералы. Это позволяет построить иерархию данных, например:
{ "squadName": "Super hero squad", "homeTown": "Metro City", "formed": 2016, "secretBase": "Super tower", "active": true, "members": [ { "name": "Molecule Man", "age": 29, "secretIdentity": "Dan Jukes", "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"] }, { "name": "Madame Uppercut", "age": 39, "secretIdentity": "Jane Wilson", "powers": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] }, { "name": "Eternal Flame", "age": 1000000, "secretIdentity": "Unknown", "powers": [ "Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel" ] } ] }
Если мы загрузим эту строку в JavaScript-код и создадим переменную с названием superHeroes
, то мы сможем получить данные из неё, например:
superHeroes.homeTown; superHeroes["active"];
Чтобы получить доступ к данным дальше по иерархии, необходимо объединять имена свойств и индексы массивов. Например, чтобы получить доступ к третьей суперспособности второго героя, нужно сделать следующее:
superHeroes["members"][1]["powers"][2];
- У нас есть переменная с именем superHeroes.
- Мы хотим получить доступ к свойству members, поэтому пишем [“members”].
- Свойство members содержит массив, заполненный объектами. Мы хотим получить доступ ко второму объекту в массиве, поэтому мы пишем [1].
- Внутри этого объекта мы хотим получить доступ к свойству powers, поэтому пишем [“powers”].
- В свойстве powers находится массив, содержащий суперсилы выбранного героя. Мы хотим получить третью суперсилу, поэтому пишем [2].
Примечания
- JSON требует двойных кавычек в названиях свойств. Одинарные кавычки недопустимы.
- Даже одна неправильно поставленная запятая или двоеточие могут привести к некорректной работе JSON-файла. Необходимо тщательно проверять любые данные, которые вы пытаетесь использовать. Проверить JSON можно с помощью такого приложения, как JSONLint.
- В отличие от JavaScript-кода, в котором свойства объектов могут быть без кавычек, в JSON в качестве свойств могут использоваться только строки, взятые в двойные кавычки.
Пример работы с JSON
Итак, давайте рассмотрим на примере, как можно использовать некоторые данные в формате JSON на веб-сайте.
Для начала создадим локальные копии файлов heroes.html и style.css. Последний файл содержит простой CSS для стилизации нашей страницы, а первый – очень простой основной HTML-код, плюс элемент <script>
, содержащий JavaScript-код:
<header> ... </header> <section> ... </section> <script> ... </script>
Мы разместили данные JSON на GitHub:
https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json.
Мы собираемся загрузить JSON в наш скрипт и отобразить данные, как показано ниже:
Функция верхнего уровня (Top-level function)
Функция верхнего уровня выглядит следующим образом:
async function populate() { const requestURL = "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json"; const request = new Request(requestURL); const response = await fetch(request); const superHeroes = await response.json(); populateHeader(superHeroes); populateHeroes(superHeroes); }
Для получения необходимых данных мы используем Fetch API. Этот API позволяет выполнять сетевые запросы для извлечения ресурсов с сервера с помощью JavaScript-кода (например, изображений, текста, JSON и даже фрагментов HTML).
В нашей функции мы используем Fetch API для получения JSON с сервера:
- мы объявляем переменную
requestURL
для хранения URL-адреса GitHub. - далее используем этот URL для инициализации объекта
Request
. - выполняем сетевой запрос с помощью функции
fetch()
, которая возвращает объектResponse
. - в итоге получаем ответ в формате JSON с помощью функции
json(
).
Примечание: API fetch()
является асинхронным, поэтому необходимо добавить ключевое слово async
перед именем функции, использующей API fetch, также необходимо ключевое слово await
перед вызовами любых асинхронных функций.
После всего этого переменная superHeroes
будет содержать объект JavaScript, основанный на JSON. Этот объект мы передаем двум функциям: первая заполняет <header>
нужными данными, а вторая создает информационную карточку для каждого героя команды и вставляет ее в <section>
.
Заполнение заголовка
Мы получили данные в формате JSON и преобразовали их в объект JavaScript. Добавим функцию:
function populateHeader(obj) { const header = document.querySelector("header"); const myH1 = document.createElement("h1"); myH1.textContent = obj.squadName; header.appendChild(myH1); const myPara = document.createElement("p"); myPara.textContent = `Hometown: ${obj.homeTown} // Formed: ${obj.formed}`; header.appendChild(myPara); }
Здесь мы сначала создаем элемент h1 с помощью createElement()
, устанавливаем его textContent
равным свойству squadName
объекта, а затем добавляем созданный элемент к заголовку с помощью appendChild()
. Аналогичную операцию мы проделываем и с абзацем: создаем его, задаем его текстовое содержимое и добавляем к заголовку.
Создание информационных карточек героя
Далее добавим следующую функцию, которая создает и отображает карточки супергероев:
function populateHeroes(obj) { const section = document.querySelector("section"); const heroes = obj.members; for (const hero of heroes) { const myArticle = document.createElement("article"); const myH2 = document.createElement("h2"); const myPara1 = document.createElement("p"); const myPara2 = document.createElement("p"); const myPara3 = document.createElement("p"); const myList = document.createElement("ul"); myH2.textContent = hero.name; myPara1.textContent = `Secret identity: ${hero.secretIdentity}`; myPara2.textContent = `Age: ${hero.age}`; myPara3.textContent = "Superpowers:"; const superPowers = hero.powers; for (const power of superPowers) { const listItem = document.createElement("li"); listItem.textContent = power; myList.appendChild(listItem); } myArticle.appendChild(myH2); myArticle.appendChild(myPara1); myArticle.appendChild(myPara2); myArticle.appendChild(myPara3); myArticle.appendChild(myList); section.appendChild(myArticle); } }
Для начала мы сохраняем свойство members
объекта JavaScript в новой переменной. Это свойство представляет собой массив, который содержит несколько объектов с информацией о каждом герое.
Далее с помощью цикла мы перебираем каждый объект в массиве и для каждого из них мы:
- Создаем несколько новых элементов:
<article>
,<h2>
, три<p>
и<ul>
. - Задаем в
<h2>
name
текущего героя. - Заполняем три абзаца информацией
secretIdentity
,age
и строкой “Superpowers:”. - Сохраняем свойство
powers
в новой константеsuperPowers
— она содержит массив со списком суперспособностей текущего героя. - Используем другой цикл для перебора суперспособностей текущего героя — для каждой из них мы создаем элемент
<li>
, помещаем туда суперсилу, затем помещаемlistItem
внутрь элемента<ul>
с помощьюappendChild( )
. - Затем мы добавляем
<h2>
,<p>
, и<ul>
в<article>
. Далее добавляем<article>
в<section>.
Порядок добавления элементов важен, поскольку именно в таком порядке они будут отображаться в HTML.
Примечание: Если у вас возникли проблемы с примером выше, попробуйте обратиться к исходному коду heroes-finished.html.
Вызов функции верхнего уровня
Наконец, нам необходимо вызвать нашу функцию верхнего уровня populate()
:
populate();
Преобразования между форматами
Приведенный выше пример был прост с точки зрения доступа к объекту JavaScript, поскольку мы преобразовали ответ сети непосредственно в объект JavaScript с помощью функции response.json().
Но иногда нам так не везет – иногда мы получаем необработанную строку JSON, и нам необходимо самостоятельно преобразовать ее в объект. А когда мы хотим отправить объект JavaScript по сети, то перед отправкой его нужно преобразовать в JSON (строку). К счастью, эти две проблемы настолько распространены в веб-разработке, что в браузерах имеется встроенный объект JSON, который содержит следующие два метода:
parse()
: Принимает в качестве параметра строку JSON и возвращает соответствующий объект JavaScript.stringify()
: Принимает в качестве параметра JS-объект и возвращает эквивалентную строку JSON.
Первую из них можно увидеть в примере heroes-finished-json-parse.html (см. исходный код).
Ключевой фрагмент кода :
async function populate() { const requestURL = "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json"; const request = new Request(requestURL); const response = await fetch(request); const superHeroesText = await response.text(); const superHeroes = JSON.parse(superHeroesText); populateHeader(superHeroes); populateHeroes(superHeroes); }
Как можно догадаться, stringify()
работает обратным образом. Попробуйте поочередно ввести в консоль следующие строки:
let myObj = { name: "Chris", age: 38 }; myObj; let myString = JSON.stringify(myObj); myString;
Здесь мы создаем объект JavaScript, затем преобразуем его в строку JSON с помощью функции stringify()
и сохраняем возвращаемое значение в новой переменной.
Вывод
В этой статье мы предоставили вам полное руководство по использованию JSON в ваших программах, включая создание и парсинг JSON, а также доступ к данным, хранящимся в нем.
Перевод статьи «Working with JSON».