cpp

Получение данных в текстовом формате

Обмен данными с помощью фрагментов HTML-страницы, фрагментов кода JavaScript или текста является самым простым способом получения результата. Ответ сервера будет сохранен в свойствах responseText и response объекта XMLHttpRequest. Для отображения результата запроса на Web-странице достаточно присвоить значение свойству innerHTML какого-либо существующего HTML-элемента. На основании вставленного фрагмента Web-браузер обновит объектную модель HTML-документа и изменит внешний вид Web-страницы без перегрузки страницы.

Рассмотрим получение данных в текстовом формате на примере. Создадим документ с формой (листинг 3.5), который будет обмениваться данными с файлом ajax.php (листинг 3.6), методами GET и POST.

Листинг 3.5. Получение данных в текстовом формате

<!doctype html>
<html lang="ru">
<head>
   <meta charset="utf-8">
   <meta name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
   <title>Получение данных в текстовом формате</title>
</head>
<body>
<div class="container my-3">
  <form action="ajax.php" method="GET" onsubmit="return false;">
    <div class="form-group">
      <input type="text" class="form-control" id="txt1">
    </div>
    <button type="button" class="btn btn-primary"
            id="btnSendGET">Отправить методом GET</button>
    <button type="button" class="btn btn-primary"
            id="btnSendPOST">Отправить методом POST</button>
  </form>
</div>
<div class="container my-3">
   <div id="div_ajax"></div>
</div>

<script>
function processReqChange(req) {
   // Обрабатываем асинхронный запрос
   try {
      if (req.readyState == 4) {
         if (req.status == 200) { // Запрос успешно обработан
            var serverData = req.responseText;
            document.getElementById('txt1').value = '';
            document.getElementById('div_ajax').innerHTML = serverData;
         }
         else {
            document.getElementById('div_ajax').innerHTML = 'Ошибка';
         }
      }
   }
   catch(e) {
      document.getElementById('div_ajax').innerHTML = 'Ошибка';
   }
}

function sendReqGET() {
   // Отправка запроса методом GET
   if ( !window.XMLHttpRequest ) {
      window.alert('Ваш Web-браузер не поддерживает XMLHttpRequest');
      return;
   }
   var txt = document.getElementById('txt1').value;
   if (txt === '') {
      window.alert('Не заполнено поле');
      return;
   }
   var url = '/ajax.php?txt1=' + encodeURIComponent(txt);
   // Создание объекта XMLHttpRequest
   var req = new XMLHttpRequest();
   // Подготовка асинхронного запроса методом GET
   req.open('GET', url, true);
   // Обработка событий
   req.onreadystatechange = function() {
      processReqChange(req);
   };
   req.onloadstart = function() {
      document.getElementById('div_ajax').innerHTML = 'Загрузка...';
   };
   // Отправляем запрос
   req.send(null);
}

function sendReqPOST() {
   // Отправка запроса методом POST
   if ( !window.XMLHttpRequest ) {
      window.alert('Ваш Web-браузер не поддерживает XMLHttpRequest');
      return;
   }
   var txt = document.getElementById('txt1').value;
   if (txt === '') {
      window.alert('Не заполнено поле');
      return;
   }
   // Передаваемые параметры
   var formData = 'txt1=' + encodeURIComponent(txt);
   // Создание объекта XMLHttpRequest
   var req = new XMLHttpRequest();
   // Подготовка асинхронного запроса методом POST
   req.open('POST', '/ajax.php', true);
   // Добавляем HTTP-заголовок
   req.setRequestHeader('Content-Type', 
                        'application/x-www-form-urlencoded');
   // Обработка событий
   req.onreadystatechange = function() {
      processReqChange(req);
   };
   req.onloadstart = function() {
      document.getElementById('div_ajax').innerHTML = 'Загрузка...';
   };
   // Отправляем запрос
   req.send(formData);
}
document.getElementById('btnSendGET').onclick = sendReqGET;
document.getElementById('btnSendPOST').onclick = sendReqPOST;
</script>
</body>
</html>

Листинг 3.6. Исходный код файла ajax.php

<?php
// Запрещаем кеширование
header('Expires: Tue, 12 May 2020 01:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
// Указываем MIME-тип и кодировку
header('Content-Type: text/html; charset=utf-8');
if ( isset($_GET['txt1']) ) {
   echo 'Метод GET – ';
   echo htmlspecialchars($_GET['txt1'], ENT_COMPAT, 'UTF-8');
}
else {
   if ( isset($_POST['txt1']) ) {
      echo 'Метод POST – ';
      echo htmlspecialchars($_POST['txt1'], ENT_COMPAT, 'UTF-8');
   }
   else {
      echo 'Данные не получены';
   }
}

После загрузки кода из листинга 3.5 на Web-странице будет отображено поле для ввода и две кнопки. При щелчке на кнопке Отправить методом GET будет вызвана функция sendReqGET(), а при щелчке на кнопке Отправить методом POST — функция sendReqPOST(). Результат выполнения запроса будет выведен в теге <div>, имеющем идентификатор div_ajax (id="div_ajax").

После заполнения формы и щелчка на кнопке Отправить методом GET внутри функции sendReqGET() получаем значение текстового поля и сохраняем его в переменной txt:

var txt = document.getElementById('txt1').value;

Далее проверяем, заполнено ли поле ввода, и, если оно не заполнено, выводим сообщение и завершаем выполнение функции:

if (txt === '') {
   window.alert('Не заполнено поле');
   return;
}

Затем формируем строку запроса, которую будем передавать методом GET. Все данные, введенные пользователем в поле ввода, перекодируем с помощью функции encodeURIComponent(). Сформированную строку сохраняем в переменной url:

var url = '/ajax.php?txt1=' + encodeURIComponent(txt);

На следующем этапе создаем объект XMLHttpRequest:

var req = new XMLHttpRequest();

Как уже говорилось ранее, мы будем сокращать код. В реальных приложениях следует создавать объект XMLHttpRequest способом, рассмотренным в листинге 3.4. Чтобы не возникло ошибки, в самом начале функции мы проверяем, поддерживает ли Web-браузер объект XMLHttpRequest. Если не поддерживает, то выводим сообщение и выходим из функции:

if ( !window.XMLHttpRequest ) {
   window.alert('Ваш Web-браузер не поддерживает XMLHttpRequest');
   return;
}

Далее с помощью метода open() подготавливаем объект к отправке асинхронного запроса методом GET:

req.open('GET', url, true);

В свойстве onreadystatechange указываем анонимную функцию, в которой вызывается функция processReqChange(). Благодаря этому можем передать объект в качестве параметра функции. Функция processReqChange() будет вызываться при каждом изменении статуса запроса:

req.onreadystatechange = function() {
   processReqChange(req);
};

С помощью метода send() отправляем запрос на сервер. Так как мы передаем данные методом GET, в качестве параметра метода send() указываем значение null:

req.send(null);

Поскольку поступление ответа от сервера может произойти через некоторое (иногда продолжительное) время, выводим сообщение, подтверждающее отправку данных:

req.onloadstart = function() {
   document.getElementById('div_ajax').innerHTML = 'Загрузка...';
};

При каждом изменении статуса запроса будет вызываться функция processReqChange(). Внутри этой функции проверяем значение свойства readyState. Если статус запроса равен 4, то ответ полностью получен с сервера и доступен для обработки:

if (req.readyState == 4) {
...
}

Наличие статуса завершения еще не гарантирует успешность выполнения запроса. Для этого мы проверяем значение свойства status. Если значение равно 200, то запрос выполнен успешно. В этом случае получаем ответ сервера с помощью свойства responseText, очищаем поле ввода и присваиваем значение элементу с идентификатором div_ajax с помощью свойства innerHTML:

if (req.status == 200) {
   var serverData = req.responseText;
   document.getElementById('txt1').value = '';
   document.getElementById('div_ajax').innerHTML = serverData;
}

Чтобы исключить различные ошибки все тело функции processReqChange() расположено внутри конструкции try...catch.

В случае заполнения формы и последующего щелчка на кнопке Отправить методом POST внутри функции sendReqPOST() мы получаем значение текстового поля и сохраняем его в переменной txt. Далее проверяем, заполнено ли поле ввода, и, если оно не заполнено, выводим сообщение и завершаем выполнение функции. Затем формируем строку запроса, которую будем передавать методом POST. Все данные, введенные пользователем в поле ввода, перекодируем с помощью функции encodeURIComponent(). Сформированную строку сохраняем в переменной formData:

var formData = 'txt1=' + encodeURIComponent(txt);

На следующем этапе создаем объект XMLHttpRequest. Далее с помощью метода open() подготавливаем объект к отправке асинхронного запроса методом POST:

req.open('POST', '/ajax.php', true);

В первом параметре указываем метод POST, а во втором — передаем путь к скрипту относительно корня сайта. Значение третьего параметра (true) указывает, что запрос будет асинхронным.

При передаче данных методом POST необходимо дополнительно указать, что данные переданы из формы. Для этого в методе setRequestHeader() указываем значение application/x-www-form-urlencoded:

req.setRequestHeader('Content-Type', 
                     'application/x-www-form-urlencoded');

Далее, как обычно, в свойстве onreadystatechange указываем функцию-обработчик. Затем с помощью метода send() отправляем запрос на сервер. В качестве параметра указываем сформированную строку запроса, которую мы сохранили в переменной formData:

req.send(formData);

Дальнейшая обработка запроса происходит точно так же, как и при отправке запроса методом GET.

Теперь рассмотрим, что происходит при получении запроса сервером. Получив запрос, сервер создаст следующие переменные окружения:

  • при передаче методом GET:
$_GET['txt1']
  • при передаче методом POST:
$_POST['txt1']

Проверить существование переменных можно с помощью функции isset(). После получения переменных можем делать с ними все, что захотим. В этом примере мы просто возвращаем отправленное значение обратно Web-браузеру, дополнительно указывая, каким методом были получены данные.

Для корректного отображения отправленной информации указывается MIME-тип и кодировка с помощью функции header():

header('Content-Type: text/html; charset=utf-8');

Если кодировка не указана сервером, то Web-браузер по умолчанию предполагает, что ответ пришел в кодировке UTF-8. Так что если данные посылаются в другой кодировке, то ее необходимо обязательно указывать.

Чтобы исключить кеширование данных, в самом начале программы мы отправляем целый набор заголовков, запрещающих кеширование:

header('Expires: Tue, 12 May 2020 01:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
Внимание!

Учебник по jQuery и AJAX
Учебник по jQuery и AJAX в формате PDF

Реквизиты

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp