- JavaScript AJAX Ответ сервера
- Свойство onreadystatechange
- Пример
- Использование функции обратного вызова
- Пример
- Свойства ответа сервера
- Методы ответа сервера
- Свойство responseText
- Пример
- Свойство responseXML
- Пример
- Метод getAllResponseHeaders()
- Пример
- Метод getResponseHeader()
- Одна функция для Ajax-запросов.
- Как вернуть данные.
- AJAX для новичков
- Что такое AJAX?
- Обмен данными
- Методы объекта XMLHttpRequest
- Свойства объекта XMLHttpRequest
- Создание объекта XMLHttpRequest
- Запрос к серверу
- Обработка ответа
- Варианты ответа от сервера
- Работа с серверными языками программирования
- Литература по теме
JavaScript AJAX Ответ сервера
Свойство onreadystatechange
Свойство readyState имеет статус XMLHttpRequest.
Свойство onreadystatechange определяет функцию, которая будет выполнена, когда readyState изменяется.
Свойство status и statusText свойство имеет статус объекта XMLHttpRequest.
Свойство | Описание |
---|---|
onreadystatechange | Определяет функцию, которая будет вызываться при изменении свойства readyState |
readyState | Содержит статус XMLHttpRequest. 0: запрос не инициализирован 1: соединение с сервером установлено 2: запрос получен 3: запрос обработки 4: запрос завершен и ответ готов |
status | 200: «OK» 403: «Запрещено» 404: «Страница не найдена» Полный список см. в Справочнике по сообщениям HTTP |
statusText | Возвращает текст статуса (например, «ОК» или «Не найдено») |
Функция onreadystatechange вызывается каждый раз, когда readyState изменения.
Когда readyState 4 и статус 200, ответ готов:
Пример
Событие onreadystatechange срабатывает в четыре раза (1-4), один раз для каждого изменения в readyState.
Использование функции обратного вызова
Функция обратного вызова — это функция, переданная в качестве параметра другой функции.
Если у вас более одной задачи AJAX на веб сайте, вы должны создать одну функцию для выполнения XMLHttpRequest объекта и одну функцию обратного вызова для каждой задачи AJAX.
Вызов функции должен содержать URL адрес и функцию, которую нужно вызвать, когда ответ будет готов.
Пример
function loadDoc(url, cFunction) <
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() <
if (this.readyState == 4 && this.status == 200) <
cFunction(this);
>
>;
xhttp.open(«GET», url, true);
xhttp.send();
>
function myFunction1(xhttp) <
// здесь выполняется действие
>
function myFunction2(xhttp) <
// здесь выполняется действие
>
Свойства ответа сервера
Свойство | Описание |
---|---|
responseText | получить данные ответа в виде строки |
responseXML | получить данные ответа как данные XML |
Методы ответа сервера
Метод | Описание |
---|---|
getResponseHeader() | Возвращает конкретную информацию заголовка из ресурса сервера |
getAllResponseHeaders() | Возвращает всю информацию заголовка из ресурса сервера |
Свойство responseText
Свойство responseText возвращает ответ сервера в виде строки JavaScript, и вы можете использовать его соответствующим образом:
Пример
Свойство responseXML
Объект XMLHttpRequest имеет встроенный анализатор XML.
Свойство responseXML возвращает ответ сервера в виде объекта XML DOM.
Используя это свойство, вы можете анализировать ответ как объект XML DOM:
Пример
Запросите файл cd_catalog.xml и проанализируйте ответ:
Метод getAllResponseHeaders()
Метод getAllResponseHeaders() возвращает всю информацию заголовка ответа сервера.
Пример
Метод getResponseHeader()
Метод getResponseHeader() возвращает конкретную информацию заголовка из ответа сервера.
Источник
Одна функция для Ajax-запросов.
Как вернуть данные.
Долго сидел и думал, какое же дать название этой статье, т.к. тема гораздо обширнее, чем просто «вернуть ответ из функции Ajax-запросов«. Сюда можно было бы приклеить и «Работа с полученным ответом на Ajax-запрос«, и «Универсальная функция Ajax-запросов«, и «Работа с объектами Promise и Deferred» , и еще массу вариантов. Но всё это сводится к одной проблеме, которая изо дня в день поднимается новичками на форумах и которую можно определить одной фразой — асинхронность выполнения Ajax-запросов.
Что же вообще это значит: «синхронное или асинхронное выполнение»? Если не особо углубляясь и, как говорится, на пальцах, то:
- Синхронное выполнение — это, когда вы сели на горшок справлять нужду, то штаны не натягиваете, пока не завершите этот процесс, а потом не воспользуетесь туалетной бумагой, а может быть еще и биде. 😉
- Асинхронное выполнение — это, когда вы поставили чайник на огонь, включили стиральную машинку и сели читать книгу. Все процессы выполняются независимо друг от друга и не дожидаясь окончания одним другого.
Надеюсь, что суть уловили. 🙂 Давайте разберем типичный ошибочный пример:
И вопрос обычно звучит в таком стиле: «Почему функция не возвращает данные? Почему всегда false?» Теперь уже, когда вы знаете разницу между синхронным и асинхронным выполнением, вы можете без труда понять, что происходит внутри функци «ajaxRequest»: инициализировали переменную «response», начался процесс ajax-запроса, но еще до его завершения, функция уже возвращает значение переменной, которое так и не успело изменится.
Как с этим бороться? Первое, что может прийти на ум и будет решение не таким уж правильным — это сделать запрос синхронным. В методе $.ajax(), за это отвечает параметр async со значение false (по умолчанию — значение true). Главный минус такого подхода в том, что на время выполнения запроса, сайт у пользователя попросту «подвиснет», а это не есть хорошо. Кроме того, это может отрицательно сказаться на выполнении каких-либо фоновых операциях. Например, если у вас есть функция, которая каждую секунду должна что-то выполнять, то на время Ajax-запроса, она так же зависнет. Поэтому синхронное выполнение, мы отложим для особых случаев, где без синхронности обойтись нельзя.
Универсальная функция для Ajax — это хорошо, но не всегда такую функцию можно сделать под конкретный проект, а понятие «универсальность» в широком смысле, тут вообще не подходит. Как минимум, ответ обрабатывается по разному, запросы могут передавать как обычные данные, так и файлы, где настройки запроса отличаются, могут отличаться функции beforeSend, complete и т.д. В этом случае, можно упростить код за счет метода $.ajaxSetup(). Основные настройки или настройки, которые будут действовать в большинстве случаев, мы можем указать в коде один раз и больше не прописывать их в методе $.ajax().
Теперь в любом месте, где нужно сделать ajax-запрос, мы прописываем только то, что отправляем и обработчик ответа:
Если же в каком-то исключительном случае, нам нужно изменить определенную настройку, то её так же дописываем. Например, в каком-то случае, нам не нужно показывать «loader» ( ) перед отправкой запроса или вместо loader-а, вывести что-то в консоль:
Это был один из вариантов, с помощью которого можно сделать код более универсальным. Теперь же перейдём непосредственно к функциям.
Вариант первый — передача в функцию обработчика ответа на Ajax-запрос:
Итак, предположим, что у нас на странице есть два элемента, объект «actions», содержащий функции для обработки данных ответа и одна функция ajax-запросов, которая принимает два аргумента: «data» — какие-то данные, передаваемые на сервер и «responseHandler» — имя функции, которая должна обработать ответ сервера (аргументов, понятное дело, что может быть и больше). После успешного завершения запроса, вызывается соответствующая функция из объекта «actions», которая принимает полученные от сервера данные (переменная «response») и заменяет ими контент соответствующего элемента. Если нам понадобится еще какой-то обработчик, то мы просто допишем в объект «actions» новую функцию, при этом что-либо изменять дополнительно уже не понадобится.
В примере, мы вручную записывали имя функции-обработчика, но это можно так же автоматизировать. Например, используя атрибут тегов «data-*»:
В итоге, у нас одна функция для Ajax-запросов, один расширяемый объект с обработчиками, один обработчик кликов для всех кнопок, а вот результат разный и тот, который нужен нам 😉
Вариант второй — используем JavaScript-объект Promise («обещание«), которой служит для отложенных и асинхронных вычислений. Проще говоря, с помощью этого объекта мы можем установить обработчик события на выполнение какой-либо задачи. В jQuery существует свой объект для работы с «обещаниями» — это объект $.Deferred(). Разбирать его по косточкам не будем, т.к. все можно найти в документации, а просто рассмотрим пару вариантов использования и один из основных методов объекта Deffered — $.when(). Изменим наш код выше таким образом:
Объект с обработчиками нам уже не нужен, т.к. мы обрабатываем ответ сервера на месте. Опции success, error и т.д. — нам так же не нужны, так как метод $.when(), создавая новый deferred-объект, следит за состоянием процесса. А в методе .then(), мы устанавливаем обработчики событий:
- doneCallbacks — функция, которая будет вызвана в случае успешно выполнения
- failCallbacks — функция вызываемая при возникновении ошибки
- И, при желании, progressCallbacks — обработчик события «progress»
Кому-то может показаться такой подход малополезным, но представим ситуацию, когда вам нужно сделать два, три или более ajax-запросов, дождаться завершения каждого, обработать ответы и только потом вывести на экран. Любители «индусского кода» не растеряются 🙂 Они напишут тонну лишнего кода, в то время, как это можно сделать достаточно легко с помощью того же метода $.when():
Функция Ajax осталась одна, ничего лишнего писать не пришлось и результат тот, которого мы ожидали.
И напоследок, покажу, как можно использовать Promise на чистом JavaScript. Сам код Ajax-запроса я описывать тут не буду, т.к. я его уже разбирал в статье Запрос на чистом JavaScript, а схематически это будет выглядеть так:
Надеюсь, что этот краткий обзор, поможет новичкам сориентироваться в правильном направлении. Более подробно про функции объекта Deferred — читайте в официальной документации 😉
Источник
AJAX для новичков
Сейчас в сети Интернет наблюдается очень активное развитие (и даже использование) новых технологий. Одна из таких технологий — AJAX.
Что такое AJAX?
AJAX — это аббревиатура, которая означает Asynchronous Javascript and XML. На самом деле, AJAX не является новой технологией, так как и Javascript, и XML существуют уже довольно продолжительное время, а AJAX — это синтез обозначенных технологий. AJAX чаще всего ассоцириуется с термином Web 2.0 и преподносится как новейшее Web-приложение.
При использовании AJAX нет необходимости обновлять каждый раз всю страницу, так как обновляется только ее конкретная часть. Это намного удобнее, так как не приходится долго ждать, и экономичнее, так как не все обладают безлимитным интернетом. Правда в этом случае, разработчику необходимо следить, чтобы пользователь был в курсе того, что происходит на странице. Это можно реализовать с использованием индикаторов загрузки, текстовых сообщений о том, что идёт обмен данными с сервером. Необходимо также понимать, что не все браузеры поддерживают AJAX (старые версии браузеров и текстовые браузеры). Плюс Javascript может быть отключен пользователем. Поэтому, не следует злоупотреблять использованием технологии и прибегать к альтернативным методам представления информации на Web-сайте.
Обобщим достоинства AJAX:
- Возможность создания удобного Web-интерфейса
- Активное взаимодействие с пользователем
- Частичная перезагрузка страницы, вместо полной
- Удобство использования
AJAX использует два метода работы с веб-страницей: изменение Web-страницы не перезагружая её, и динамическое обращение к серверу. Второе может осуществляться несколькими способами, в частности, XMLHttpRequest, о чем мы и будем говорить, и использование техники скрытого фрейма.
Обмен данными
Для того, чтобы осуществлять обмен данными, на странице должен быть создан объект XMLHttpRequest, который является своеобразным посредником между Браузером пользователя и сервером (рис. 1). С помощью XMLHttpRequest можно отправить запрос на сервер, а также получить ответ в виде различного рода данных.
Обмениваться данными с сервером можно двумя способами. Первый способ — это GET-запрос. В этом запросе вы обращаетесь к документу на сервере, передавая ему аргументы через сам URL. При этом на стороне клиента будет логично использовать функция Javascript`а escape для того, чтобы некоторые данные не прервали запрос.
Не рекомендуется делать GET-запросы к серверу с большими объемами данных. Для этого существует POST-запрос.
Клиент часть, написанная на Javascript, должна обеспечивать необходимую функциональность для безопасного обмена с сервером и предоставлять методы для обмена данными любым из вышеперечисленных способов. Серверная часть должна обрабатывать входные данные, и на основе их генерировать новую информацию (например, работая с базой данных), и отдавать ее обратно клиенту. Например, для запроса информации с сервера можно использовать обычный GET-запрос с передачей нескольких и небольших по размеру параметров, а для обновления информации, или добавления новой информации потребуется использовать уже POST-запрос, так как он позволяет передавать большие объемы данных.
Как уже было сказано, AJAX использует асинхронную передачу данных. Это значит, что пока идёт передача данных, пользователь может совершать другие, необходимые ему действия. В это время следует оповестить пользователя о том, что идёт какой-либо обмен данными, иначе пользователь подумает, что произошло что-то не то и может покинуть сайт, или повторно вызвать «зависшую», по его мнению, функцию. Индикация во время обмена данными в приложении Web 2.0 играет очень важную роль: посетители могли еще не привыкнуть к таким способам обновления страницы.
Ответ от сервера может быть не только XML, как следует из названия технологии. Помимо XML, можно получить ответ в виде обычного текста, или же JSON (Javascript Object Notation). Если ответ был получен простым текстом, то его можно сразу вывести в контейнер на странице. При получении ответа в виде XML, обычно происходит обработка полученного XML документа на стороне клиента и преобразование данных к (X)HTML. При получении ответа в формате JSON клиент должен лишь выполнить полученный код (функция Javascript`а eval) для получения полноценного объекта Javascript. Но здесь нужно быть осторожным и учитывать тот факт, что с использованием этой технологии может быть передан вредоносный код, поэтому перед выполнением полученного с сервера кода следует его тщательно проверить и обработать. Существует такая практика, как «холостой» запрос, при котором никакой ответ от сервера не приходит, лишь изменяются данные на стороне сервера.
В разных браузерах данный объект обладает разными свойствами, но в целом он совпадает.
Методы объекта XMLHttpRequest
Заметьте, что названия методов записаны в том же стиле (Camel-style), что и другие функции Javascript. Будьте внимательны при их использовании.
abort() — отмена текущего запроса к серверу.
getAllResponseHeaders() — получить все заголовки ответа от сервера.
getResponseHeader(«имя_заголовка») — получить указаный заголовок.
open(«тип_запроса»,«URL»,«асинхронный»,«имя_пользователя»,«пароль») — инициализация запроса к серверу, указание метода запроса. Тип запроса и URL — обязательные параметры. Третий аргумент — булево значение. Обычно всегда указывается true или не указывается вообще (по умолчанию — true). Четвертый и пятый аргументы используются для аутентификации (это очень небезопасно, хранить данные об аутентификации в скрипте, так как скрипт может посмотреть любой пользователь).
send(«содержимое») — послать HTTP запрос на сервер и получить ответ.
setRequestHeader(«имя_заголовка»,«значение») — установить значения заголовка запроса.
Свойства объекта XMLHttpRequest
onreadystatechange — одно из самых главных свойств объекта XMLHttpRequest. С помощью этого свойства задаётся обработчик, который вызывается всякий раз при смене статуса объекта.
readyState — число, обозначающее статус объекта.
responseText — представление ответа сервера в виде обычного текста (строки).
responseXML — объект документа, совместимый с DOM, полученного от сервера.
status — состояние ответа от сервера.
statusText — текстовое представление состояния ответа от сервера.
Следует подробнее расммотреть свойство readyState:
- 0 — Объект не инициализирован.
- 1 — Объект загружает данные.
- 2 — Объект загрузил свои данные.
- 3 — Объек не полностью загружен, но может взаимодействовать с пользователем.
- 4 — Объект полностью инициализирован; получен ответ от сервера.
Именно опираясь на состояние готовности объекта можно представить посетителю информацию о том, на какой стадии находится процесс обмена данными с сервером и, возможно, оповестить его об этом визуально.
Создание объекта XMLHttpRequest
Как уже говорилось выше, создание данного объекта для каждого типа браузера — уникальный процесс.
Например, для создания объекта в Gecko-совместимых браузерах, Konqueror`е и Safari, нужно использовать следующее выражение:
var Request = new XMLHttpRequest();
А для Internet Explorer`а используется следующее:
var Request = new ActiveXObject(«Microsoft.XMLHTTP»);
var Request = new ActiveXObject(«Msxml2.XMLHTTP»);
Теперь, чтобы добиться кроссбраузерности, необходимо сложить все функции в одну:
После всего этого можно создавать данный объект и не беспокоится за работоспособность на популярных браузерах. Но создать объект можно в разных местах. Если создать его глобально, то в определенный момент времени возможен будет только один запрос к серверу. Можно создавать объект всякий раз, как происходит запрос к серверу (это почти полностью решит проблему).
Запрос к серверу
Алгоритм запроса к серверу выглядит так:
- Проверка существования XMLHttpRequest.
- Инициализация соединения с сервером.
- Посылка запрса серверу.
- Обработка полученных данных.
Для создания запроса к серверу мы создадим небольшую функцию, которая будет по функциональности объединять в себе функции для GET и POST запросов.
Создавать запрос стало намного проще. Для примера напишем функцию, которая будет получать содержимое файла на сервере и выводить его в контейнер.
Именно таким образом происходит взаимодействие с сервером.
Обработка ответа
В предыдущем примере мы сделали функцию запроса к серверу. Но она, по сути, небезопасна, так как мы не обрабатываем состояния объекта и состояния ответа от сервера.
Дополним наш код, чтобы он смог выводить визуальное оповещение о процессе загрузки.
Как вы уже знаете, объект XMLHttpRequest позволяет узнать статус ответа от сервера. Воспользуемся этой возможностью.
Варианты ответа от сервера
От сервера можно получить данные нескольких видов:
- Обычный текст
- XML
- JSON
Если вы получаете обычный текст, то вы можете сразу же направить его в контейнер, то есть на вывод. При получении данных в виде XML вы должны обработать данные с помощью DOM-функций, и представить результат с помощью HTML.
JSON — это объектная нотация Javascript. С ее помощью можно представить объект в виде строки (здесь можно привести аналогию с функцией сериализации). При получении JSON-данных вы должны выполнить их, чтобы получить полноценный объект Javascript и произвести с ним необходимые операции. Помните, что такая передача данных и выполнение их не являются безопасными. Вы должны следить за тем, что поступает на исполнение.
Пример кода JSON:
При получении такого кода, производим следующее действие:
var responsedata = eval(«(» + Request.responseText + «)»)
После выполнения данного кода вам будет доступен объект responsedata.
Работа с серверными языками программирования
Такая работа ничем не отличается от обычной. Для примеров я возьму PHP в качестве серверного языка. В клиентской части ничего не изменилось, но серверная часть теперь представлена PHP-файлом.
По традиции, начнем с приветствия нашему замечательному миру:
При обращении к этому файлу клиенту вернется строка Hello, World. Как вы понимаете, это представляет широчайшие возможности для построения приложений. На основе передачи аргументов при вызове сервера с помощью XMLHttpRequest можно сделать параметризацию вывода, тем самым обеспечив обширную функциональность Web-приложения.
Помимо PHP, можно использовать любой другой серверный язык программирования.
Литература по теме
Статья написана с целью рассказать новичкам о работе AJAX изнутри. Если Вам кажется, что что-то написано неточно или неверно, поправляйте, пожалуйста, меня, для того, чтобы создать достойную статью вместе.
Конечно, если есть возможность, стоит использовать существующие фреймворки, я считаю. Но знать «как оно работает» всё-же необходимо.
Источник