Опубликован: 19.03.2014 | Уровень: для всех | Доступ: платный
Лекция 11:

Обмен данными между мобильным виджетом клиента и сервером

Аннотация: Управление процессом обмена данными между мобильным виджетом Windows Phone и веб-сервером. Объект XMLHttpRequest. Методы для инициирования запроса и управления им. Методы GET и POST. Обращение к веб-серверу для получения данных. Свойства ответа сервера. Обращение к веб-серверу для отправки данных. Виртуальная форма FormData. Примеры приложений. Особенности тестирования.

Методы управления процессом коммуникации. Объект XMLHttpRequest

Основным инструментом, который предоставляет HTML5 для взаимодействия клиента с веб-сервером, является объект XMLHttpRequest. Его неофициально называют коммуникационным API. Объект XMLHttpRequest впервые был создан корпорацией Microsoft для того, чтобы улучшить веб-версию своей программы электронной почты Outlook, но он постепенно распространился на многие современные сетевые технологии. В настоящее время его применяют большинство JavaScript- клиентских приложений, взаимодействующих с сервером. Ключевая идея, лежащая в основе объекта XMLHttpRequest состоит в том, что он позволяет коду JavaScript самостоятельно направлять запросы к серверу, когда приложению требуется передать данные серверному сценарию или получить данные от него. Эти запросы осуществляются асинхронно; это означает, что мобильное устройство остается доступным для работы даже в процессе выполнения такого запроса. Более того, его пользователь никогда даже не догадывается о выполняющемся за кулисами запросе (если только не выводится соответствующее извещение или индикатор хода выполнения). Объект XMLHttpRequest является идеальным инструментом как для получения данных с веб-сервера, так и для отправки данных на сервер. Он является центральным в наборе методов, носящих название AJAX (от англ. Asynchronous JavaScript And XML - "асинхронный JavaScript и XML") , и именно благодаря XMLHttpRequest, клиенское приложение может обращаться к серверу, отправлять ему данные и получать ответ, не обновляя своих страниц и поэтому делая их более оперативными.

Хотя в названии этого объекта присутствует аббревиатура XML, технология его применения не накладывает ограничений на формат передаваемых данных. Данные можно пересылать как в виде XML, так и в JSON, HTML или просто неструктурированным текстом. Разработчик может самостоятельно создать формат для передачи данных. Однако нужно учитывать, что при пересылке используется текстовый протокол HTTP, и потому при использовании метода GET данные должны передаваться в виде текста (то есть бинарные данные следует кодировать, к примеру в base64). При использовании метода POST в кодировании нет необходимости.

Для создания объекта взаимодействия с веб-сервером в JavaScript - коде используется конструктор XMLHttpRequest(). Он возвращает объект XMLHttpRequest, на базе которого создается запрос, а затем прослушивать события для управления процессом коммуникации. Объект, создаваемый конструктором XMLHttpRequest(), предлагает следующие важные методы для инициирования и управления запросом:

  • open(method, url, async). Настраивает ждущий запрос. В атрибуте method нужно указать HTTP - метод, с помощью которого будет открыто соединение, например GET или POST. GET - используется для запроса содержимого указанного ресурса. POST - применяется для передачи пользовательских данных заданному ресурсу. Атрибут url объявляет местоположение сценария, который будет обрабатывать запрос. Атрибут async содержит булево значение, определяющее, по какому типу будет происходить коммуникация: синхронно (false) или асинхронно (true). Если необходимо, в параметрах метода также можно указать имя пользователя и пароль.
  • send(data). Фактически, инициирует запрос. У объекта XMLHttpRequest есть несколько версий данного метода, предназначенных для обработки данных разных типов. Атрибут data необязательный, но если он используется, то в качестве его значения можно указать объект ArrayBuffer, бинарный блок, документ, строку или объект виртуальной формы FormData. При отсутствии данных необходимо указать параметр null.
  • abort (). Отменяет запрос.

Наиболее важные свойства объекта XMLHttpRequest:

  • onreadystatechange. Это обработчик события типа EventListener, которое происходит при каждой смене текущего состояния объекта. Имя должно быть записано в нижнем регистре.
  • readyState. Текущее состояние объекта (0 - не инициализирован, 1 - открыт, 2 - отправка данных, 3 - получение данных и 4 - данные загружены).
  • responseText. Текст ответа на запрос типа DOMString. Если состояние не 3 или 4, возвращает пустую строку.
  • responseXML. Текст ответа на запрос в виде XML, который затем может быть обработан посредством DOM. Если состояние не 4, возвращает null.

План работы с объектом XMLHttpRequest можно представить следующим образом:

  • создание экземпляра объекта XMLHttpRequest;
  • открытие соединения;
  • установка обработчика события (нужно делать после открытия и до отправки запроса);
  • отправка запроса.

Расмотрим примеры обращения к серверу средствами объекта XMLHttpRequest для получения и отправки данных.

Обращение к веб-серверу для получения данных

Создадим небольшое приложение, в котором будем извлекать информацию из файла на сервере, применяя для этого метод GET. Нам понадобится HTML-документ с кнопкой, которая будет инициировать запрос к серверу на передачу данных мобильному клиенту:

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" href="css/ajax.css" />
    <script type="text/javascript" src="js/ajax.js"></script>
    <title>Ajax</title>
     </head>
  <body>
    <h3>Чтение файла с сервера</h3><br/>
      <section id ="formbox">
      <form name ="form">
       <p><input type ="button" id ="button" name ="button" value="ВЫПОЛНИТЬ"/></p><br />
      </form>
          </section>
      <section id ="databox"> </section>
  </body>
</html>

Применяем только базовые стили для оформления полей на экране:

#formbox {
    float: left;
    padding: 60px;
    border: 1px solid #999999;
}
#databox {
    float: left;
    width: 500px;
    margin-left: 20px;
    padding: 20px;
    border: 1px solid #999999;
}
h3 {font-family: Verdana, Arial, Helvetica, sans-serif;}
body{
	background-color:#F2EBC7;
	color:#962D3E;
	font-family:Verdana, Geneva, sans-serif;
    font-size:10px;
}

JavaScript - код в этом примере будет считывать содержимое из файла на сервере и выводить его на экран. Никакие данные на сервер не отправляются - мы всего лишь выполняем запрос GET и показываем полученную информацию:

function initiate() {
    databox = document.getElementById('databox');
    var button = document.getElementById('button');
    button.addEventListener('click', read, false);
}
function read() {
    var url = "http://www.minkbooks.com/content/trailer.ogg"
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState == 4) {
               databox.innerHTML = 'Сервер прислал:' + request.responseText;
        }
    }
    request.open("GET", url, true);
    request.send(null);
}
window.addEventListener('load', initiate, false);

Для отладки этого кода нужно реальное мобильное устройство и желателен текстовый файл на вашем сервере. При отсутствии этого, можно протестировать код под браузером и взять файл с "чужого" сервера в Интернет. Кстати, для отладки и тестирования данного примера был взят файл по адресу "http://www.minkbooks.com/content/trailer.ogg". Результат тестирования запроса к серверу:


Рис. 19.1.

В JavaScript - коде этого примера представлена типичная функция initiate(). Она вызывается после полной загрузки документа. Функция создает ссылку на databox и добавляет прослушиватель события click к кнопке. Когда пользователь нажимает кнопку "Выполнить", происходит вызов функции read(). Здесь мы можем наблюдать все приведенные ранее методы в действии. В первую очередь объявляется URL-адрес файла, который мы собираемся прочитать. На следующем шаге с помощью конструктора XMLHttpRequest() создается объект, который сразу же присваивается переменной request. Для этой переменной мы используем прослушиватель onreadystatechange и анонимную функцию function(), которая начнет выполняться после загрузки файла с сервера. Запускается процесс вызовом методов open() и send(). Поскольку в этом запросе никакие данные не отправляются, метод send() пуст (передается значение null), однако методу open() требуются все атрибуты, иначе он не сможет настроить запрос. Используя этот метод, мы объявляем запрос типа GET, указывая URL-адрес файла для считывания, и тип операции (true, так как нам требуется асинхронная операция).

Асинхронный тип операции подразумевает, что браузер продолжает обрабатывать код, пока происходит считывание файла. О завершении операции нас информирует значение текущего состояния readyState = 4. После того как файл будет загружен, сработает событие onreadystatechange и анонимная функция заменит содержимое поля databox значением свойства responseText, на этом процесс завершится. Обработка полученной от сервера информации определяется свойствами его ответа.

Дмитрий Белов
Дмитрий Белов

Каким образом можно создать точку останова? Например, если в Лекции 8 в примере, который демонстрирует возможность <canvas> для работы с готовыми изображениями (последний в лекции) в цикле
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++) {
sx = 300 * i; sy = 350 * j;
contextNow.drawImage(img, sx, sy);}
поставить точку останова, то при запуске отладки проекта точка становится пустой окружностью с сообщением: В настоящий момент попадание в точку останова не произойдет. Нет загруженных символов для этого документа. Как все-таки создать точку останова и пройти по шагам весь код?

Акмарал Кубыгулова
Акмарал Кубыгулова
Казахстан, Астана
Илья Макаров
Илья Макаров
Россия, Пермь, МОУ СОШ 71, 2013