Меню Закрыть

Javascript ajax асинхронный запрос

Содержание

В интерактивности — статические html сайты — это прошлое. Динамические с использованием CGI (или модулей сервера, например Apache) и баз данных, когда сервер при отправки формы формирует страницу и показывает ее после обновления — чуть современней, но все же во многих областях, где требуется практически сопостовимая с десктопными приложениями интерактивность — так же угасают. На смену приходят интерактивные функциональные программы, в полной мере взаимодействующие с пользователем; информация, полученная от сервера практически мгновенно отображается на экране без перезагрузке страницы. Речь я виду об AJAX’e, что в расшифровке "асинхронный JavaScript и XML" (термин ввел Джесс Гарретт). А если более подробно, то — "асинхронный JavaScript + CSS + DOM + XMLHttpRequest".

Методы объекта XMLHttpRequest

Все нижеизложанные методы и свойства — общие для Internet Explorer 5, Mozilla, Netscape 7, и соответственно, использовать их можно безопасно.

abort()
обрывает текущий запрос

getAllResponseHeaders()
возвращает полный набор заголовков ответа (названий и значений) в виде строки

getResponseHeader( )
возвращает строковое значение заголовка, название которого указано в параметре .

]]])
Присвоение параметров (метода, URL, и других) текущему запросу.

send( )
Посылает запрос

setRequestHeader( , )
Установка в отправляемом запросе заголовка со значением

Свойства объекта XMLHttpRequest

onreadystatechange
событие, возникающее при смене статуса объекта

readyState
значения статуса (integer), может принимать следующие значения: 0 = неинициализирован (uninitialized); 1 = "идет загрузка" (loading); 2 = "загружен" (loaded); 3 = "интерактивен" (interactive) 4 = "выполнен" (complete)

responseText
строка с возвращенными сервером данными

responseXML
DOM-совместимый объект-документ с возвращенными сервером данными

status
стандартный HTTP код статуса, например 404 (для "Not Found") или 200 (для "OK")

statusText
текстовое сообщение статуса

Здесь все необходимые свойства и методы этого объекта, которые помогут нам решить наш таск. Опишем последовательность наших действий:

1. Создание экземпляра объекта XMLHttpRequest.
2. Объявление обработчика события onreadystatechange нашего экземпляра .
3. Открытие соединения с указанием типа запроса, URL и других параметров.
4. Посыл запроса.

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

Итак, пункт первый — создание экземпляра объекта. Вот здесь всплывает особенность обеспечения кроссбраузерности. Конструкция создания объекта различна: в IE 5+ она реализована через ActiveXObject, а в остальных браузерах (Mozilla, Netscape и Safari) — как встроенный объект типа XMLHttpRequest.

Для Internet Explorer:

Для всех остальных:

Таким образом, чтобы обеспечить кроссбраузерность, нужно лишь проверять наличие объектов window.XMLHttpRequest и window.ActiveXObject и применять соответствующий вызов создания экземпляра.

Далее по плану — создание обработчика событий и открытие соединения. Это весьма просто:

Ну и последний пункт — посыл запроса — метод send() (для версии без ActiveX в качестве параметра нужно передать null).

После запуска метода send() начинает работать вышеуказанный обработчик события onreadystatechange. Собственно, этот обработчик — основная часть программы. В нем обычно перехватываются все возможные коды состояния запроса и вызываются соответствующие действия, а также перехватываются возможные ошибки.

Исходя из всего вышесказанного, JavaScript код будет примерно следущим:

Теперь HTML-формы нашего примера:

Обратите внимение на фрагмент, выделенный зеленным цветом — событие onClick кнопки "Поиск". Мы вызываем функицю doLoad(…), в качестве параметра которой передаем адрес backend-скрипта, выполняющего поиск в базе зарегистрированного пользователя. О backend-скрипе чуть позже, имя его мы определили как ajaxsearch.php. Также GET-параметром скрипту мы передаем переменную search, со значением, взятым из поля ввода для ника.

И, как было сказано выше, объявим дополнительные HTML-элементы (в нашем случае — это невидимые слои) для отображения полученного содержимого и окна загрузки с возможностью отмены:

Ну что ж, с frontend’ом разобрались, переходим к backend’у — скрипт ajaxsearch.php. И вновь мы сталкиваемся с небольшими нюансами: для того, чтобы PHP-скрипт корректно работал с XMLHttpRequest, он (скрипт) должен посылать ряд заголовков. А именно: тип содержимого и его кодировку (особенно важно, если вы работаете с кириллицей), а также параметры кеширования — любое кеширование должно быть отключено (ну это и понятно — необходимо иметь свежую информацию).

Послать эти заголовки можно, примерно, так:

И еще одна особенность: если вы будете выводит данные в формате text/plane (в нашем случае — text/html, поэтому нас это не каснется, но все же — чтобы знать), помните, что спецсимволы такие как n, t, r и т.д., обрабатываются по умолчанию только в строках с двойными кавычками:

Ну и теперь весьма банальный PHP-скрипт получения данных из базы (а банальный, потому что предполагается, что у вас уже есть навыки работы с базами данных в PHP). Вид скрипта следующий (в найденых никах мы подсвечиваем буквы запроса красным цветом и выводим все это в виде таблицы):

Читайте также:  Как заблокировать открытие сайта в яндексе

Ну вот, друзья, собственно, и все на сегодня.

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/xmlhttprequest.

Объект XMLHttpRequest (или, как его кратко называют, «XHR») даёт возможность из JavaScript делать HTTP-запросы к серверу без перезагрузки страницы.

Несмотря на слово «XML» в названии, XMLHttpRequest может работать с любыми данными, а не только с XML.

Использовать его очень просто.

Пример использования

Как правило, XMLHttpRequest используют для загрузки данных.

Для начала посмотрим на пример использования, который загружает файл phones.json из текущей директории и выдаёт его содержимое:

Далее мы более подробно разберём основные методы и свойства объекта XMLHttpRequest , в том числе те, которые были использованы в этом коде.

Настроить: open

Этот метод – как правило, вызывается первым после создания объекта XMLHttpRequest .

Задаёт основные параметры запроса:

method – HTTP-метод. Как правило, используется GET либо POST, хотя доступны и более экзотические, вроде TRACE/DELETE/PUT и т.п.

URL – адрес запроса. Можно использовать не только http/https, но и другие протоколы, например ftp:// и file:// .

При этом есть ограничения безопасности, называемые «Same Origin Policy»: запрос со страницы можно отправлять только на тот же протокол://домен:порт , с которого она пришла. В следующих главах мы рассмотрим, как их можно обойти.

async – если установлено в false , то запрос производится синхронно, если true – асинхронно.

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

«Асинхронный запрос» означает, что браузер отправит запрос, а далее результат нужно будет получить через обработчики событий, которые мы рассмотрим далее.

  • user , password – логин и пароль для HTTP-авторизации, если нужны.

Заметим, что вызов open , в противоположность своему названию ( open – англ. «открыть») не открывает соединение. Он лишь настраивает запрос, а коммуникация инициируется методом send .

Отослать данные: send

Именно этот метод открывает соединение и отправляет запрос на сервер.

В body находится тело запроса. Не у всякого запроса есть тело, например у GET-запросов тела нет, а у POST – основные данные как раз передаются через body .

Отмена: abort

Вызов xhr.abort() прерывает выполнение запроса.

Ответ: status, statusText, responseText

Основные свойства, содержащие ответ сервера:

status HTTP-код ответа: 200 , 404 , 403 и так далее. Может быть также равен 0 , если сервер не ответил или при запросе на другой домен. statusText Текстовое описание статуса от сервера: OK , Not Found , Forbidden и так далее. responseText Текст ответа сервера.

Есть и ещё одно свойство, которое используется гораздо реже:

Если сервер вернул XML, снабдив его правильным заголовком Content-type: text/xml , то браузер создаст из него XML-документ. По нему можно будет делать запросы xhr.responseXml.querySelector(". ") и другие.

Оно используется редко, так как обычно используют не XML, а JSON. То есть, сервер возвращает JSON в виде текста, который браузер превращает в объект вызовом JSON.parse(xhr.responseText) .

Синхронные и асинхронные запросы

Если в методе open установить параметр async равным false , то запрос будет синхронным.

Синхронные вызовы используются чрезвычайно редко, так как блокируют взаимодействие со страницей до окончания загрузки. Посетитель не может даже прокручивать её. Никакой JavaScript не может быть выполнен, пока синхронный вызов не завершён – в общем, в точности те же ограничения как alert .

Если синхронный вызов занял слишком много времени, то браузер предложит закрыть «зависшую» страницу.

Из-за такой блокировки получается, что нельзя отослать два запроса одновременно. Кроме того, забегая вперёд, заметим, что ряд продвинутых возможностей, таких как возможность делать запросы на другой домен и указывать таймаут, в синхронном режиме не работают.

Из всего вышесказанного уже должно быть понятно, что синхронные запросы используются чрезвычайно редко, а асинхронные – почти всегда.

Для того, чтобы запрос стал асинхронным, укажем параметр async равным true .

Если в open указан третий аргумент true (или если третьего аргумента нет), то запрос выполняется асинхронно. Это означает, что после вызова xhr.send() в строке (1) код не «зависает», а преспокойно продолжает выполняться, выполняется строка (2) , а результат приходит через событие (3) , мы изучим его чуть позже.

Полный пример в действии:

Событие readystatechange происходит несколько раз в процессе отсылки и получения ответа. При этом можно посмотреть «текущее состояние запроса» в свойстве xhr.readyState .

Читайте также:  Закачать шагомер в телефон бесплатно андроид

В примере выше мы использовали только состояние 4 (запрос завершён), но есть и другие.

Запрос проходит их в порядке 0 → 1 → 2 → 3 → … → 3 → 4 , состояние 3 повторяется при каждом получении очередного пакета данных по сети.

Пример ниже демонстрирует переключение между состояниями. В нём сервер отвечает на запрос digits , пересылая по строке из 1000 цифр раз в секунду.

При состоянии readyState=3 (получен очередной пакет) мы можем посмотреть текущие данные в responseText и, казалось бы, могли бы работать с этими данными как с «ответом на текущий момент».

Однако, технически мы не управляем разрывами между сетевыми пакетами. Если протестировать пример выше в локальной сети, то в большинстве браузеров разрывы будут каждые 1000 символов, но в реальности пакет может прерваться на любом байте.

Чем это опасно? Хотя бы тем, что символы русского языка в кодировке UTF-8 кодируются двумя байтами каждый – и разрыв может возникнуть между ними.

Получится, что при очередном readyState в конце responseText будет байт-полсимвола, то есть он не будет корректной строкой – частью ответа! Если в скрипте как-то по-особому это не обработать, то неизбежны проблемы.

HTTP-заголовки

XMLHttpRequest умеет как указывать свои заголовки в запросе, так и читать присланные в ответ.

Для работы с HTTP-заголовками есть 3 метода:

Устанавливает заголовок name запроса со значением value .

Нельзя установить заголовки, которые контролирует браузер, например Referer или Host и ряд других (полный список тут).

Это ограничение существует в целях безопасности и для контроля корректности запроса.

Особенностью XMLHttpRequest является то, что отменить setRequestHeader невозможно.

Повторные вызовы лишь добавляют информацию к заголовку, например:

Возвращает значение заголовка ответа name , кроме Set-Cookie и Set-Cookie2 .

Возвращает все заголовки ответа, кроме Set-Cookie и Set-Cookie2 .

Заголовки возвращаются в виде единой строки, например:

Между заголовками стоит перевод строки в два символа "
" (не зависит от ОС), значение заголовка отделено двоеточием с пробелом ": " . Этот формат задан стандартом.

Таким образом, если хочется получить объект с парами заголовок-значение, то эту строку необходимо разбить и обработать.

Таймаут

Максимальную продолжительность асинхронного запроса можно задать свойством timeout :

При превышении этого времени запрос будет оборван и сгенерировано событие ontimeout :

Полный список событий

Современная спецификация предусматривает следующие события по ходу обработки запроса:

  • loadstart – запрос начат.
  • progress – браузер получил очередной пакет данных, можно прочитать текущие полученные данные в responseText .
  • abort – запрос был отменён вызовом xhr.abort() .
  • error – произошла ошибка.
  • load – запрос был успешно (без ошибок) завершён.
  • timeout – запрос был прекращён по таймауту.
  • loadend – запрос был завершён (успешно или неуспешно)

Используя эти события можно более удобно отслеживать загрузку ( onload ) и ошибку ( onerror ), а также количество загруженных данных ( onprogress ).

Ранее мы видели ещё одно событие – readystatechange . Оно появилось гораздо раньше, ещё до появления текущего стандарта.

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

IE8,9: XDomainRequest

В IE8 и IE9 поддержка XMLHttpRequest ограничена:

  • Не поддерживаются события, кроме onreadystatechange .
  • Некорректно поддерживается состояние readyState = 3 : браузер может сгенерировать его только один раз во время запроса, а не при каждом пакете данных. Кроме того, он не даёт доступ к ответу responseText до того, как он будет до конца получен.

Дело в том, что, когда создавались эти браузеры, спецификации были не до конца проработаны. Поэтому разработчики браузера решили добавить свой объект XDomainRequest , который реализовывал часть возможностей современного стандарта.

А обычный XMLHttpRequest решили не трогать, чтобы ненароком не сломать существующий код.

Мы подробнее поговорим про XDomainRequest в главе XMLHttpRequest: кросс-доменные запросы. Пока лишь заметим, что для того, чтобы получить некоторые из современных возможностей в IE8,9 – вместо new XMLHttpRequest() нужно использовать new XDomainRequest .

Теперь в IE8,9 поддерживаются события onload , onerror и onprogress . Это именно для IE8,9. Для IE10 обычный XMLHttpRequest уже является полноценным.

IE9- и кеширование

Обычно ответы на запросы XMLHttpRequest кешируются, как и обычные страницы.

Но IE9- по умолчанию кеширует все ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают. Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например Cache-Control: no-cache .

Впрочем, использовать заголовки типа Expires , Last-Modified и Cache-Control рекомендуется в любом случае, чтобы дать понять браузеру (не обязательно IE), что ему следует делать.

Читайте также:  Как найти плотность зная температуру и давление

Альтернативный вариант – добавить в URL запроса случайный параметр, предотвращающий кеширование.

Например, вместо xhr.open(‘GET’, ‘service’, false) написать:

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

Итого

Типовой код для GET-запроса при помощи XMLHttpRequest :

Мы разобрали следующие методы XMLHttpRequest :

  • open(method, url, async, user, password)
  • send(body)
  • abort()
  • setRequestHeader(name, value)
  • getResponseHeader(name)
  • getAllResponseHeaders()
  • timeout
  • responseText
  • responseXML
  • status
  • statusText
  • onreadystatechange
  • ontimeout
  • onerror
  • onload
  • onprogress
  • onabort
  • onloadstart
  • onloadend

Задачи

Выведите телефоны

Создайте код, который загрузит файл phones.json из текущей директории и выведет все названия телефонов из него в виде списка.

Исходный код просто выводит содержимое файла (скачайте к себе):

27.02.2019

AJAX запрос это обращение с клиентской стороны т.е. от браузера к серверу, не перезагружая страницы. AJAX – это технология JavaScript для обращения к серверу без перезагрузки страницы.

Рассмотрим примеры AJAX запросов:

XMLHttpRequest , — экземпляр данного класса включает в себя набор методов для работы в протоколах HTTP и HTTPS. AJAX запрос, — это комплекс выполняемых задач, в режиме «запрос-ответ».

Каждый запрос к серверу, включает в себя ->

  • Указание метода HTTP (GET POST)
  • Запрашиваемого URL (пути до файла на сервере, который будет обрабатывать наш запрос)
  • Установка заголовков на пример: "application/x-www-form-url" или "application/x-www-form-urlencoded" или "application/json" или "text-plain"
  • Данные передаваемые на сервер (тело запроса)

Каждый ответ от сервера включает в себя

  • Код статуса (успешно или нет отработала сторона сервера)
  • Заголовки HTTP/HTTPS
  • Данные передаваемые от сервера к клиенту (браузеру)

Элементы кода, которые будут использованы в примерах.

XMLHttpRequest , — это класс, для работы AJAX.

request – это переменная или константа в которой будет хранится, — экземпляр класса XMLHttpRequest, объект с набором методов.

url – это путь до файла на сервере, который будет обрабатывать наш запрос. В примерах с GET методом, в нем будут передаваться данные со стороны клиента.

.open() – это метод где мы задаем, первым параметром, — метод передачи данных, а вторым url.

.setRequestHeader() – это метод для указания передаваемых заголовков, здесь мы можем указать что данные идут в url либо закрытым способом, либо хотим получить данные от сервера в json формате.

.send() – это последний этап создания http запроса. С помощью него также можно передать тело запроса т.е. данные от браузера к серверу. Можно не чего не передавать или прямо указать null.

onreadystatechange – это событие которое случится когда нам придет ответ от сервера.

readyState – это метод экземпляра, который сообщает статус HTTP-запроса, вот возможные значения которые он может дать:

Значение Описание
Метод open() не вызван
1 Метод open() вызван
2 Получены заголовки ответа
3

Получено тело ответа

4 Передача ответа выполнена

status или statusText – возвращают статус http заголовков, нам нужен ответ 200. Хотя бывают и 404 или 500.

.responseText – данные, которые придут от сервера в виде строки.

.response – данные вернуться в json формате, тут как бы мы преобразуем сразу в объект, и дальше работаем уже как с объектом.

.text() – используется в запросе fetch, возвращает строку.

.json() – используется в запросе fetch, возвращает json обращенный в объект.

1. GET AJAX запрос на чистом JavaScript

Делаем запрос на чистом JavaScript, например к файлу ajax_quest.php, который находится на сервере, и будет возвращать то что мы ему передали.

2. POST AJAX запрос на чистом JavaScript к PHP файлу на сервере

Принцип такой же как и у GET запроса, но не забываем что GET запросом данные отправляются открыто. У POST запроса данные скрыты, и в большинстве своем желательно использовать POST запросы.

3. JSON AJAX POST запрос к серверу, на чистом Javascript

Запрос на чистом Javascript. Получаем данные в JSON формате.

4. JQuery GET & POST AJAX запрос к PHP на сервере

Работаем с сервером через фреймворк JQuery.

5. Fetch GET на чистом Javascript

Fetch обертка над XHR

6. Запрос на чистом Javascript "Vanila" Fetch + POST метод

7. Fetch POST + JSON

Данный метод сейчас мало какой браузер поддерживает. Но есть костыли. Этот код работает, попробуйте разобраться что к чему. С удовольствием узнаю как лучше тут поступать.

8. Кросдоменный запрос JSONP Fetch + GET метод в github

Кросдоменный AJAX запрос в репозиторий github. Репозиторий возвращает json объект с именами.

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.