НЕ МОЛЧИ!!!    Сделай что-нибудь, чтобы остановить войну России в Украине.
...бойтесь людей равнодушных - именно с их молчаливого согласия происходят все самые ужасные преступления на свете.   ("Репортаж с петлёй на шее")

Пример запроса AJAX JSON

Приведен пример запроса AJAX JSON с детальным описанием, описан JSON формат

В предыдущей статье, посвященной AJAX передаче данных в формате XML указывалось, что он удобен для копирования или переноса каких-либо данных со сложной структурой, например, содержимое баз данных. Но за удобство надо платить, в данном случае издержки вызваны тем, что в XML довольно высок удельный вес служебной информации, кроме того, тратятся ресурсы сначала на создание самого формата, а затем на его расшифровку. Как говорится, нет в мире совершенства, но стремиться к нему надо. Поэтому был предложен JSON формат, который получился намного эффективнее своего предшественника.

Формат JSON

Задача данной статьи полнее рассказать об AJAX запросах, поэтому описание формата будет кратким. Желающим получше с ним познакомиться — милости прошу в Google, тем более, что формат прост, как все гениальное. Но одну ссылку все-таки укажу — это описание JSON на официальном сайте.
JSON — это текстовый формат описания данных, он не зависит от языка программирования. Основное достоинство JSON в том, что он легко читается людьми и имеет предельно мало служебных символов. Основные правила при создании формата: ключ должен быть заключен в двойные кавычки, а через двоеточие — его значение, которое может быть одним из следующих типов — string, boolean, number, array, object или null.
Для сравнения приведем XML формат каких-то данных и его JSON аналог:

XML
<page>
<type>article</type>
<title>AJAX JSON запрос</title>
<rubric>Примеры AJAX</rubric>
</page>
 
JSON
{"type":"article","title":"AJAX JSON запрос","rubric":"Примеры AJAX"}

Комментарии, как говорится, излишни.

Взаимодействие Javascript с JSON

В Javascript взаимодействовать с этим форматом очень просто. Ниже приведен скрипт, который выводит на экран фрагмент JSON описания списка статей:

<script type="text/javascript">

/* фрагмент верстки с кнопкой, по которой происходит отображение элемента списка
<input id="show" type="button" value="Отобразить" onclick="show()">
*/

// присваиваем переменной список статей в формате JSON var articles = '
{ "rubric0": [
{"type":"article","title":"Простой AJAX запрос","author": "Иванов" },
{"type":"article","title":"AJAX XML запрос","author": "Петров" },
{"type":"article","title":"AJAX JSON запрос","author": "Пупкин" },
],
"rubric1": [
{"type":"article","title":"Заказное ПО","author": "Сидоров" },
{"type":"article","title":"Типы сайтов","author": "Скворцов" },
{"type":"article","title":"Виды лицензий ОС Windows","author": "Тяпкин" },
],
"rubric2": [
{"type":"article","title":"Javascript и CSS, введение","author": "Яковлев" },
{"type":"article","title":"Javascript и CSS, поддержка браузерами","author": "Знайкин" },
]
}';


function show() { //выводим на экран часть описания
let rubric = 'AJAX запросы';
let title = articles.rubric0['2']['title'];
let author = articles.rubric0['2']['author'];
let str = 'Вы сейчас читаете статью "' + title + '" из рубрики "' + rubric + '", автор ' + author;
alert(str);
}
</script>

Убедиться в работе скрипта можно по кнопке «Отобразить», которая выведет одно из свойств списка.



Простота использования формата в Javascript, объясняется тем, что у них общие корни, на это указывает само сокращение JSON (JavaScript Object Notation), которое  переводится как «запись объектов Javascript». Для разбора JSON данных  можно использовать функции eval() или parse(). Но надо заметить, что первая из них таит в себе скрытую угрозу. Если запрос будет содержать вредоносный код, то бесконтрольное использование eval() для обработки приходящих данных может обернуться большими неприятностями. С помощью глобального объекта JSON, метод JSON.stringify(value, replacer, space) обеспечивает преобразование объектов Javascript в формат JSON, избавляя нас от этой рутинной работы, а метод JSON.parse(text, reviver), в отличие от eval() обеспечивает безопасное преобразование JSON в объекты Javascript.
 

Недостатки JSON формата

Несколько слов о недостатках формата. В JSON нельзя сообщить о кодировке текстовой строки. Во-первых, согласно стандарту JSON предлагается кодировать только в UTF-8, допустимы кодировки UTF-16 и UTF-32 с порядком следования байт BE и LE, во-вторых, можно использовать коды ASCI, а другие символы представлять в виде escape-последовательностей: \xXX для 8-битных кодировок и \uXXXX для Юникода, в-третьих, плюнув на стандарт, можно использовать любую кодировку, если у клиента и сервера один «хозяин» и договариваться о кодировке через заголовок HTTP протокола:

xmlHttp.setRequestHeader("Content-Type","application/json;charset=windows-1251")
 
Надо добавить, что формат развивается, последние версии добавили полезных свойств.

А теперь вернемся к основной теме статьи.

Пример AJAX передачи данных в формате JSON

Ниже представлены строки ввода, наша задача — отправить и получить данные в JSON формате. При успешном завершении под строками ввода  отобразится отклик сервера.

Укажите свое имя:
Укажите фамилию:
Ваш возраст:
 
Ответ сервера:  
  

Вот текст основных скриптов, использованных в примере, вспомогательная обвязка здесь не приведена, чтобы не отвлекать от главного.

Что в нем происходит. Обработчик кнопки «Отправить» send() получает данные ввода, после их проверки на вшивость создает JSON строку введенных данных и далее производит AJAX запрос, который описан ниже.


<script type="text/javascript">
var addr = "путь_к_обработчику_запроса/postJSON.php";

// обработчик кнопки Отправить function send()
{
var inp = getInput();
var isOk = checkInput(inp);
if (!isOk) {
return;
}
var personjs = getJSON(inp);
sendData(addr, personjs, getData);
}

// возвращает объект с данными ввода
function getInput()
{
var obj = new Object();
obj.name = document.getElementById('name').value;
obj.family = document.getElementById('family').value;
obj.age = document.getElementById('age').value;
return obj;
}

// возвращает входной объект в формате JSON
function getJSON(obj)
{
var res = JSON.stringify(obj);
return res;
}

// управляет работой AJAX запроса
function sendData(addr, output, callback)
{
var request = new XMLHttpRequest();
request.responseType = "json";
request.open('POST', addr);
request.addEventListener("readystatechange", () => {
callback(request);
});
request.send(output);
}

// обрабатывает отклик сервера
function getData(request)
{
if (request.readyState == 4 && request.status == 200) {
var target = document.getElementById('response');
target.style.color = 'blue';
target.innerHTML = 'Здравствуйте, ' + request.response.name + '<br> Вы указали свой возраст = ' + request.response.age;
}
} </script>

Небольшой комментарий по AJAX запросу, поскольку остальное все прозрачно, включая получение JSON строки, как указывалось выше с помощью метода глобального объекта JSON.stringify().

Метод sendData() осуществляет запрос, ему передаются адрес обработчика на сервере, отправляемые данные и функция обработки отклика сервера. Вначале создается экземпляр AJAX запроса, следующей строкой мы указываем серверу в каком формате прислать отклик. Метод request.open() производит инициализацию запроса. Следующей строкой устанавливается функция обработки на изменение состояния запроса, в качестве ее используется функция обратного вызова, переданная во входных параметрах, в нашем случае это getData(). Ей передается объект запроса request, в этом методе мы дожидаемся  окончания успешного запроса и обрабатываем отклик request.response, который, как видно из кода, нам передается в виде объекта.

Хочу заметить, что окончание запроса (readyState == 4) еще не означает, что все в порядке, поэтому нужно также условие успешного завершения (status == 200). Кроме кода 200 может прийти, какой угодно — 404, 403, 419, 500 и т.п. Чтобы отследить любой ответ, надо в обработчике ответа по окончанию запроса анализировать значение свойства request.status и/или его текстовый аналог request.statusText, примерно так.   

if (request.readyState == 4) {
  if (request.status == 200){
    // обработка результата
  } else {
  // обработка ошибки
    alert( request.status + ': ' + request.statusText ); // например, 404: Not Found
  }
}