JSON представляет один из наиболее популярных форматов хранения и передачи данных. Особенно часто JSON используется при передачи данных через ajax-запросы. Для получения json с помощью XMLHttpRequest следует выполнить две настройки:
Чтобы ответ сервера рассматривался как объект json, свойству responseType передается значение "json". Браузеры, которые поддерживают это значение, гарантируют, что ответ может быть прочитан непосредственно как объект JavaScript.
xhr.responseType = "json";
Также при отправке запроса для заголовка Accept следует задать значение "application/json":
xhr.setRequestHeader("Accept", "application/json");В качестве сервера, как и в прошлой статье, будем использовать Node.js как наиболее простой вариант, но естественно при желании можно использовать любую другую технологию серверного уровня или какой-нибудь веб-сервер.
Итак, определим для проекта на жестком диске папку, в которой создадим три файла:
index.html: главная страница приложения
data.json: файл с данными в формате json
app.js: файл приложения сервера, который будет использовать Node.js
Файл data.json будет представлять загружаемые данные и пусть будет иметь следующее содержимое:
{
"users": [
{
"name": "Tom",
"age": 39,
"contacts":
{
"email": "tom@smail.com",
"phone": "+1234567890"
}
}, {
"name": "Bob",
"age": 43,
"contacts":
{
"email": "bob@tmail.com",
"phone": "+1334567181"
}
}, {
"name": "Sam",
"age": 28,
"contacts":
{
"email": "sam@xmail.com",
"phone": "+1434567782"
}
}
]
}
Здесь элемент users представляет набор пользователей, каждый из которых представлен элементом user. Для каждого такого элемента определены два атрибута: name (имя пользователя) и age (возраст пользователя). И также элемент user имеет вложенный элемент contacts, который представляет контактные данные пользователя в виде вложенных элементов phone и email.
Файл app.js будет представлять код сервера Node.js. Определим в нем следующий код:
const http = require("http");
const fs = require("fs");
http.createServer((request, response)=>{
// если запрошены данные xml
if(request.url == "/data"){
fs.readFile("data.json", (_, data) => response.end(data));
}
else{
fs.readFile("index.html", (_, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Сервер запущен по адресу http://localhost:3000"));
Вкратце пробежимся по коду. Сначала подключаются пакеты с функциональностью, которую мы собираемся использовать:
const http = require("http"); // для обработки входящих запросов
const fs = require("fs"); // для чтения файлов с жесткого диска
Для создания сервера применяется функция http.createServer(). В эту функцию передается функция-обработчик, которая вызывается каждый раз, когда к серверу приходит запрос.
Эта функция имеет два параметра: request (содержит данные запроса) и response (управляет отправкой ответа).
В функции-обработчике с помощью свойства request.url мы можем получить путь к ресурсу, к которому пришел запрос.
Так, в данном случае, если пришел запрос по пути "/data", то оправляем data.json:
if(request.url == "/data"){
fs.readFile("data.json", (_, data) => response.end(data));
}
Для считывания файла применяется функция fs.readFile. Первый параметр функции - адрес файла (в данном случае предполагается, что файл находится в одной папке с файлом сервера server.js). Второй параметр - функция, которая вызывается после считывания файла и получет его содержимое через свой второй параметр data.
Для всех остальных запросов отправляем в ответ файл index.html:
else{
fs.readFile("index.html", (_, data) => response.end(data));
}
В конце с помощью функции listen() запускаем веб-сервер на 3000 порту. То есть сервер будет запускаться по адресу http://localhost:3000/
Для получения файла "data.json" с сервера определим в файле index.html следующий код:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
const json = xhr.response;
console.log(json);
}
};
xhr.open("GET", "/data"); // GET-запрос к /data
xhr.responseType = "json"; // устанавливаем тип ответа
xhr.setRequestHeader("Accept", "application/json"); // принимаем только json
xhr.send(); // выполняем запрос
</script>
</body>
</html>
Для получения данных отправляем запрос по адресу "/data". Чтобы полученные данные автоматически были распарсены в документ JSON,
свойству responseType присваиваем значение "json".
xhr.responseType = "json";
Кроме того, следует установить для заголовка Accept значение "application/json":
xhr.setRequestHeader("Accept", "application/json");
В обработчике события onload объект JSON доступен через свойство response, который в
данном случае просто выводится на консоль:
xhr.onload = () => {
if (xhr.status == 200) {
const json = xhr.response;
console.log(json);
}
};
После определения всех файлов в консоли перейдем к папке сервера с помощью команды cd и запустим сервер с помощью команды node server.js
C:\app>node server.js Сервер запущен по адресу http://localhost:3000
После запуска сервера мы можем перейти в браузере по адресу http://localhost:3000, нам отобразится страница, в javascript-коде произойдет обращение по адресу "/data". Сервер в ответ отправит содержимое файла data.json, и консоль барузера отобразит это содержимое:
В полученном в примере выше объекте JSON мы можем обращаться к свойствам, извлекая из объекта нужные нам данные. Например, пусть нам надо вывести данные о пользователях из xml в таблицу на веб-страницу. Для этого изменим код index.html следующим образом:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>METANIT.COM</title>
</head>
<body>
<div id="content"></div>
<script>
const contentDiv = document.getElementById("content");
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
const json = xhr.response;
const table = createTable();
// выбираем все элементы user
const users = json.users;
for (let i = 0; i < users.length; i++) {
const user = users[i];
const row = createRow(user.name, user.age, user.contacts.email);
table.appendChild(row);
}
contentDiv.appendChild(table);
}
};
xhr.open("GET", "/data");
xhr.responseType = "document";
xhr.setRequestHeader("Accept", "text/xml");
xhr.send();
// создаем таблицу
function createTable() {
const table = document.createElement("table");
const headerRow = document.createElement("tr");
const nameColumnHeader = document.createElement("th");
const ageColumnHeader = document.createElement("th");
const contactColumnHeader = document.createElement("th");
nameColumnHeader.appendChild(document.createTextNode("Name"));
ageColumnHeader.appendChild(document.createTextNode("Age"));
contactColumnHeader.appendChild(document.createTextNode("Contacts"));
headerRow.appendChild(nameColumnHeader);
headerRow.appendChild(ageColumnHeader);
headerRow.appendChild(contactColumnHeader);
table.appendChild(headerRow);
return table;
}
// создаем одну строку для таблицы
function createRow(userName, userAge, userContact) {
const row = document.createElement("tr");
const nameColumn = document.createElement("td");
const ageColumn = document.createElement("td");
const contactColumn = document.createElement("td");
nameColumn.appendChild(document.createTextNode(userName));
ageColumn.appendChild(document.createTextNode(userAge));
contactColumn.appendChild(document.createTextNode(userContact));
row.appendChild(nameColumn);
row.appendChild(ageColumn);
row.appendChild(contactColumn);
return row;
}
</script>
</body>
</html>
В данном случае загружаем таблицу на страницу в элемент с идентификатором "content", который получаем в коде JavaScript в элемент contentDiv
const contentDiv = document.getElementById("content");
Для создания таблицы определены две вспомогательные функции. Функция createTable создает элемент table с одной строкой - заголовками столбцов. Функция createRow принимает через параметры имя, возраст и контакты пользователя и для них создает строку.
В основной части кода выполняем запрос на сервер. Получив данные JSON, выбираем массив объектов user:
const json = xhr.response; const table = createTable(); // выбираем все объекты user const users = json.users;
Далее перебираем все объекты user, выбираем у каждого объекта свойства name, age и contacts.email и создаем по ним строку в таблице:
for (let i = 0; i < users.length; i++) {
const user = users[i];
const row = createRow(user.name, user.age, user.contacts.email);
table.appendChild(row);
}
Таким образом, при обращении к странице index.html будут загружены данные в формате JSON, и по ним будет создана таблица: