Создание функций mysql. Хранимые процедуры и триггеры. Синтаксис создания триггера

Осуществляет запрос к серверу без перезагрузки страницы. Это низкоуровневый метод, обладающий большим количеством настроек. Он лежит в основе работы всех остальных методов ajax. Имеет два варианта использования:

url — адрес запроса.
settings — в этом параметре можно задать настройки для данного запроса. Задается с помощью объекта в формате {имя:значение, имя:значение...} . Ни одна из настроек не является обязательной. Установить настройки по умолчанию можно с помощью метода $.ajaxSetup() .

Список настроек

↓ название :тип (значение по умолчанию)

При выполнении запроса, в заголовках (header) указываются допустимые типы содержимого, ожидаемого от сервера. Значения этих типов будут взяты из параметра accepts.

По умолчанию, все запросы без перезагрузки страницы происходят асинхронно (то есть после отправки запроса на сервер, страница не останавливает свою работу в ожидании ответа). Если вам понадобиться синхронное выполнение запроса, то установите параметр в false . Кроссдоменные запросы и запросы типа "jsonp" не могут выполняться в синхронном режиме.

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

Это поле содержит функцию, которая будет вызвана непосредственно перед отправкой ajax-запроса на сервер. Такая функция может быть полезна для модификации jqXHR-объекта (в ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest). Например, можно изменить/указать нужные заголовки (headers) и.т.д. Объект-jqXHR будет передан в функцию первым аргументом. Вторым аргументом передаются настройки запроса.

В этом поле можно указать дополнительные заголовки запроса (header). Эти изменения будут введены до вызова beforeSend, в которой могут быть произведены окончательные правки заголовков.

При переводе этой настройки в true , запрос будет выполнен со статусом "успешно", лишь в случае, если ответ от сервера отличается от предыдущего ответом. jQuery проверяет этот факт обращаясь к заголовку Last-Modified. Начиная с jQuery-1.4, кроме Last-Modified проверяется и "etag" (оба они предоставляются сервером и необходимы для оповещения браузера о том, что запрашиваемые данные с сервера не изменены с предыдущего запроса).

Позволяет установить статус источника страницы локальным (как если бы это происходило по протоколу file), даже если jQuery распознал его иначе. Библиотека решает, что страница запущена локально в случае следующих протоколов: file, *-extension, и widget.

Рекомендуется устанавливать значение параметраisLocal глобально — с помощью функциии $.ajaxSetup() , а не в настройках отдельных ajax-запросов.

Определяет имя параметра, который добавляется в url при jsonp-запросе (по умолчанию, используется "callback" — "httр://siteName.ru?callback=...").

Начиная с jQuery-1.5, указав в этом параметре false , вы предотвратите добавление в url дополнительного параметра. В этом случае необходимо явно установить значение свойства jsonpCallback. Например так: {jsonp:false, jsonpCallback:"callbackName"} .

Определяет имя функции, которая будет вызвана при ответе сервера на jsonp-запрос . По умолчанию, jQuery генерирует произвольное название этой функции, что является более предпочтительным вариантом, упрощающим работу библиотеки. Один из причин, при котором стоит указывать собственную функцию обработки jsonp-запроса, является улучшение кеширования GET-запросов.

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

По умолчанию, все передаваемые на сервер данные, предварительно преобразуются в строку (url-формата: fName1=value1&fName2=value2&...) соответствующую "application/x-www-form-urlencoded". Если вам необходимо отправить данные, которые нельзя подвергать подобной обработке (например документ-DOM), то следует отключить опцию processData.

Этот параметр используется для кроссдоменных ajax-запросов типа GET, dataType при этом может быть или "jsonp", или "script". Определяет кодировку, в которой будет выполнен кроссдоменный запрос. Это необходимо, в случае, если сервер на чужом домене использует кодировку, отличную от кодировке на сервере родного домена.

(Эта настройка появилась в jQuery-1.5) набор пар, в котором кодам выполнения запроса сопоставляются функции, которые при этом будет вызваны. Например, для кода 404 (страницы не существуют) можно сделать вывод сообщения на экран:

$.ajax ({ statusCode: { 404 : function () { alert ("Страница не найдена" ) ; } } } ) ;

Функции, реагирующие на коды удачного выполнения запроса будут получать те же аргументы, что и функции-обработчики удачного выполнения запроса (указанные в параметре success), а функции, срабатывающие на коды ошибок, будут такими же, как и у error-функций.

Функция, которая будет вызвана в случае удачного завершения запроса к серверу. Ей будут переданы три параметра: данные, присланные сервером и уже прошедшие предварительную обработку (которая отлична для разных dataType). Второй параметр — строка со статусом выполнения. Третий параметр содержит объект jqXHR (в более ранних версиях библиотеки (до 1.5), вместо jqXHR используется XMLHttpRequest). Начиная с jQuery-1.5, вместо одной функции, этот параметр может принимать массив функций.

Время ожидания ответа от сервера. Задается в в миллисекундах. Если это время будет превышено, запрос будет завершен с ошибкой и произойдет событие error (см. описание выше), которое будет иметь статус "timeout".

Время отсчитывается с момента вызова функции $.ajax . Может случиться так, что в этот момент будет запущено несколько других запросов и браузер отложит выполнение текущего запроса. В этом случае timeout может завершиться, хотя фактически, запрос даже еще не был запущен.

В jQuery-1.4 и младше, при завершении времени ожидания, объект XMLHttpRequest перейдет в состояние ошибки и доступ к его полям может вызвать исключение. В Firefox 3.0+ запросы типа script и JSONP не будут прерваны при превышении времени ожидания. Они будут завершены даже после того как это время истечет.

Функция, которая предоставит объект XMLHttpRequest. По умолчанию, для браузеров IE этим объектом является ActiveXObject, а в остальных случаях это XMLHttpRequest. С помощью этого параметра вы можете внедрить собственную версию этого объекта.

(Эта настройка появилась в jQuery-1.5.1) Набор пар {имя:значене} для изменения/добавления значений соответствующих полей объекта XMLHttpRequest . Например, можно установить его свойство withCredentials в true , при выполнении кроссдоменного запроса:

$.ajax ({ url: a_cross_domain_url, xhrFields: { withCredentials: true } } ) ;

В jQuery-1.5 свойство withCredentials не поддерживается нативным XMLHttpRequest и при кроссдоменном запросе это поле будет проигнорировано. Во всех следующих версиях библиотеки, это исправлено.

Обработчики событий

Настройки beforeSend, error, dataFilter, success и complete (их описание есть в предыдущем разделе) позволяют установить обработчики событий, которые происходят в определенные моменты выполнения каждого ajax-запроса.

beforeSend происходит непосредственно перед отправкой запроса на сервер. error происходит в случае неудачного выполнения запроса. dataFilter происходит в момент прибытия данных с сервера. Позволяет обработать "сырые" данные, присланные сервером. success происходит в случае удачного завершения запроса. complete происходит в случае любого завершения запроса.

Пример простого использования. Выведем сообщение при удачном выполнении запроса:

$.ajax ({ url: "ajax/test.html" , success: function () { alert ("Load was performed." ) ; } } ) ;

Начиная с jQuery-1.5, метод $.ajax() возвращает объект jqXHR, который помимо прочего реализует интерфейс deferred , что позволяет задавать дополнительные обработчики выполнения. Помимо стандартных для объекта deferred методов .done(), .fail() и.then() , с помощью которых можно устанавливать обработчики, в jqXHR реализованы.success(), .error() и.complete() . Это сделано для соответствия привычным названиям методов, с помощью которых устанавливаются обработчики выполнения ajax-запросов. Однако начиная с jQuery-1.8 эти три метода станут нежелательными для использования .

Для некоторых типов запросов, таких как jsonp или кроссдоменных GET-запросов, не предусматривается использование объектов XMLHttpRequest. В этом случае, передаваемые в обработчики XMLHttpRequest и textStatus будут содержать значение undefined .

Внутри обработчиков, переменная this будет содержать значение параметра context . В случае, если он не был задан, this будет содержать объект настроек.

Параметр dataType

Функция $.ajax() узнает о типе присланных сервером данных от самого сервера (средствами MIME). Кроме этого, существует возможность лично указать (уточнить), как следует интерпретировать эти данные. Это делается с помощью параметра dataType . Возможные значения этого параметра:

"xml" — полученный xml-документ будет доступен в текстовом виде. С ним можно работать стандартными средствами jQuery (также как и с документом html). "html" — полученный html будет доступен в текстовом виде. Если он содержит скрипты в тегах , то они будут автоматически выполнены, только когда html-текст будет помещен в DOM. "script" — полученные данные будут исполнены как javascript. Переменные, которые обычно содержат ответ от сервера будут содержать объект jqXHR . "json", "jsonp" — полученные данные будут предварительно преобразованы в javascript-объект. Если разбор окажется неудачным (что может случиться, если json содержит ошибки), то будет вызвано исключение ошибки разбора файла. Если сервер, к которому вы обращаетесь, находится на другом домене, то вместо json следует использовать jsonp . Узнать о json и jsonp можно на википедии . "text" — полученные данные окажутся доступными в виде обычного текста, без предварительной обработки.

Замечание 1 : когда запрос отправляется на сторонний домен (что возможно только с dataType равным jsonp или script), обработчики ошибки выполнения (error), а так же глобальные события не сработают.

Замечание 2 : тип данных, заданный в dataType не должен противоречить предоставляемой сервером MIME-информации. Например, xml-данные должны быть представлены сервером как text/xml или application/xml . Если это не будет выполнено, jquery попытается конвертировать полученные данные в указанный тип (подробнее об этом в разделе Converters).

Отправка данных на сервер

По умолчанию, запрос к серверу осуществляется HTTP-методом GET. При необходимости сделать запрос методом POST, нужно указать соответствующее значение в настройке type . Данные, отправляемые методом POST будут преобразованы в UTF-8, если они находятся в другой кодировке, как того требует стандарт W3C XMLHTTPRequest.

Параметр data может быть задан либо строкой в формате key1=value1&key2=value2 (формат передачи данных в url), либо объектом с набором пар {имя:значение} — {key1: "value1", key2: "value2"} . В последнем случае, перед отправкой данных jQuery преобразует заданный объект в строку, с помощью $.param() . Однако, это преобразование можно отменить, указав в настройке processData значение false . Преобразование в строку нежелательно, например, в случае отправки на сервер xml-объекта. В этом случае, желательно изменить настройку contentType с application/x-www-form-urlencoded на более подходящий mime-тип .

Замечание: большинство браузеров не позволяют проводить ajax-запросы на ресурсы с доменами, поддоменами и протоколами, отличными от текущего. Однако, это ограничение не распространяется на запросы типа jsonp и script .

Получение данных с сервера

Полученные от сервера данные, могут быть предоставлены в виде строки или объекта, в зависимости от значения параметра dataType (см. пункт dataType выше). Эти данные всегда доступны в первом параметре обработчика выполнения ajax-запроса:

$.ajax ({ url: "some.php" , success: function (data) { alert ( "Прибыли данные: " + data ) ; } } ) ;

Для типов text и xml , присланные сервером данные будут доступны так же и в jqXHR , а именно в его полях responseText или responseXML соответственно.

Продвинутые настройки

Используя параметр global можно отключать выполнение обработчиков событий (.ajaxSend(), .ajaxError() и др.) для отдельных запросов. Это может быть полезно, например в случае, если в этих обработчиках запускается/останавливается анимация загрузки. Тогда если некоторые запросы выполняются очень часто и быстро, то для них полезно будет отключить выполнение обработчиков. Для кроссдоменных script и jsonp запросов параметр global отключается автоматически.

Если для совершения запроса к серверу необходимы данные аутентификации (логин/пароль), то их можно указать в настройках username и password ajax-запроса.

На выполнение запроса к серверу отводится определенное время. Если в течении этого времени сервер не присылает ответ, то запрос завершается с ошибкой (статус "timeout"). Время ожидания ответа от сервера можно изменить, задав необходимое значение (в миллисекундах) в настройке timeout .

Может так случиться, что кодировка хоста отличается от кодировки запрашиваемого в ajax-запросе javascript файла. В таких случаях необходимо указать кодировку последнего в настройке scriptCharset .

В большинстве случаев, ajax-запрос происходит асинхронно, однако в некоторых случаях может понадобиться последовательное выполнение запроса (когда дальнейшее выполнение скрипта невозможно, без получения ответа от сервера). Сделать запрос синхронным можно если отключить настройку async . Однако стоит помнить, что в таком случае станица будет "подвисать" при ожидании ответа от сервера.

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

Наиболее простым вариантом использования будет вызов $.ajax() без задания параметров:

$.ajax () ; // на сервер будет отправлен GET-запрос на url-адрес текущей страницы и без указания каких-либо параметров.

Если нужно подгрузить и выполнить js-файл, то это можно сделать следующим образом:

$.ajax ({ type: "GET" , url: "test.js" , dataType: "script" } ) ;

Сделаем POST-запрос на сервер, указав при этом два параметра и оповестим пользователя о удачно завершенном запросе:

$.ajax ({ type: "POST" , url: "some.php" , data: "name=John&location=Boston" , success: function (msg) { alert ( "Прибыли данные: " + msg ) ; } } ) ;

Обновим содержимое нужной html-страницы:

$.ajax ({ url: "test.html" , cache: false , success: function (html) { $("#results" ) .append (html) ; } } ) ;

Сделаем синхронный запрос к серверу. Пока запрос будет выполняться, страница не будет реагировать на действия пользователя:

// присланные от сервера данные, запишем в переменную html var html = $.ajax ({ url: "some.php" , async: false } ) .responseText ;

В качестве параметра, отправим на сервер xml-объект. Для его корректной передачи необходимо отменить предварительное преобразование параметров (processData:false). В качестве обработчика удачного завершения запроса укажем пользовательскую функцию handleResponse:

var xmlDocument = [ create xml document] ; $.ajax ({ url: "page.php" , processData: false , data: xmlDocument, success: handleResponse } ) ;

Расширенный подход

Начиная с jQuery-1.5 появились три новых направления, позволяющие использовать $.ajax() еще более глубоко. Первый из них (Prefilters) позволяет провести дополнительные манипуляции, непосредственно перед отправкой запроса. С помощью второго подхода (Converters) можно указать jQuery, как следует конвертировать полученные от сервера данные, если они не соответствуют ожидаемому формату. Третий подход (Transports) является наиболее низкоуровневым, он позволяет самостоятельно организовать запрос к серверу.

Prefilters

Этот подход состоит в установке обработчика, вызываемого перед выполнением каждого ajax-запроса. Этот обработчик предшествует выполнению любых других обработчиков ajax. Устанавливается он с помощью функции $.ajaxPrefilter() :

$.ajaxPrefilter (function (options, originalOptions, jqXHR) { } ) ;

Где
options — настройки текущего запроса,
originalOptions — настройки по умолчанию,
jqXHR jqXHR-объект данного запроса.

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

var currentRequests = { } ; $.ajaxPrefilter (function (options, originalOptions, jqXHR) { if (options.abortOnRetry ) { if (currentRequests[ options.url ] ) { currentRequests[ options.url ] .abort () ; } currentRequests[ options.url ] = jqXHR; } } ) ;

В ajaxPrefilter удобно обрабатывать и существующие настройки. Например так можно изменить кросс-доменный запрос на перенаправленный через сервер своего домена:

$.ajaxPrefilter (function (options) { if (options.crossDomain ) { options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url ) ; options.crossDomain = false ; } } ) ;

Кроме этого, можно указывать значения dataType на которых сработает prefilter. Так, к примеру, можно указать типы json и script:

$.ajaxPrefilter ( "json script" , function (options, originalOptions, jqXHR) { // Изменяем настройки (options), проверяем базовые настройки (originalOptions) и объект jqXHR } ) ;

И наконец, можно изменить значение dataType , вернув необходимое значение:

$.ajaxPrefilter (function (options) { // изменим dataType на script, если url соответствует определенным условиям if (isActuallyScript(options.url ) ) { return "script" ; } } ) ;

Такой подход гарантирует не только то, что запрос изменит свой тип на script, но и то, что остальные prefilter-обработчики с указанием этого типа в первом параметре, будут также выполнены.

Converters

Этот принцип заключается в установке обработчика, который сработает, если указанный в настройках dataType не совпадет с типом данных, присланных сервером.

Converters является настройкой ajax, поэтому может быть задан глобально:

// так можно задать обработчик, который сработает, если вместо // указанного вами в dataType типа mydatatype придут данные типа text $.ajaxSetup ({ converters: { "text mydatatype" : function ( textValue ) { if (valid( textValue ) ) { // обработка переданного текста return mydatatypeValue; } else { // если присланные сервером данные совсем не соответствуют ожидаемым, // можно вызвать исключение. throw exceptionObject; } } } } ) ;

Converters поможет при введении собственного (пользовательского) dataType. Важно отметить , что в названии такого dataType должны использоваться только строчные буквы! Запрос данных, упомянутого выше типа "mydatatype", мог бы выглядеть следующим образом:

$.ajax ( url, { dataType: "mydatatype" } ) ;

AJAX и jQuery. Динамическое обновление контента. Основы (изменения от 03.01.2012)

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

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

jQuery - JavaScript-framework, библиотека, позволяющая более удобно использовать некоторые возможность Javascript, такие как: создание визуальных эффектов, обработка событий, работа с DOM и поддержка AJAX.

Скачать последнюю версию jQuery и подробно ознакомиться со всеми возможностями можно на сайте разработчика: http://www.jquery.com/

В данной статье мы будем рассматривать только одну функцию библиотеки jQuery, а именно функцию $.ajax(). Эта функция позволяет нам как передавать данные на сервер, так и получать ответы от сервера и все это в фоновом режиме, без перезагрузки страницы. Настройка приема или передачи данных зависит от параметров, с которыми вызывается функция $.ajax(). Основные из них будут рассмотрены ниже. Подробнее о параметрах можно прочесть в руководстве по jQuery.

Перейдем к рассмотрению примеров.

Важно!
Для того, чтобы примеры работали корректно, необходимо:
1. Все файлы должны быть записаны в кодировке UTF-8.
2. Скрипты должны выполняться на веб-сервере, а не запускаться в браузере, как файл.

Пример 1. Динамическое обновление контента по таймеру

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

Содержимое файла index.html.

function show() { $.ajax({ url: "time.php", cache: false, success: function(html){ $("#content").html(html); } }); } $(document).ready(function(){ show(); setInterval("show()",1000); });

В коде имеются несколько особенностей, поясним их.

1. Подключение библиотеки jQuery происходит в заголовке HTML файла, для этого записана данная строка.

Сам файл jquery.js - находится в той же папке, что и файлы примера.

2. В теле документа создается контейнер, в который мы будем загружать контент.

3. Странная, на первый взгляд, функция $(document).ready() требуется для корректной работы jQuery, к тому же в ней мы можем выполнить все приготовления к работе программы. В нашем случае мы вызываем функцию show(), в которой прописан механизм получения контента из другого файла, и настраиваем таймер, так, чтобы функция show() вызывалась один раз в секунду.

$(document).ready(function(){ show(); setInterval("show()",1000); });

4. Функция show() состоит из обращения к функции $.ajax() с определенным рядом параметров, которая позволяет нам в фоновом режиме получить информацию из внешнего файла на сервере.

$.ajax({ url: "time.php", cache: false, success: function(html){ $("#content").html(html); } });

Рассмотрим используемые параметры функции $.ajax().

Url: "time.php" Обращается к файлу time.php для получения контента. cache: false Результаты запросов не кэшируются. success: function(html){ $("#content").html(html); } При успешном выполнении запроса, управление переходит функции, которая получает контент в качестве параметра и записывает его контейнер. Запись в контейнер происходит вот в этой строке:
$("#content").html(html);

Содержимое файла time.php.

Смысл работы файла time.php - выводим текущее время на экран.

Скачать исходные файлы примера (16,6 кб):

Пример 2. Динамическое обновление контента по выбору пользователя

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

Содержимое файла index.html.

Какую страницу желаете открыть?

$(document).ready(function(){ $("#btn1").click(function(){ $.ajax({ url: "page1.html", cache: false, success: function(html){ $("#content").html(html); } }); }); $("#btn2").click(function(){ $.ajax({ url: "page2.html", cache: false, success: function(html){ $("#content").html(html); } }); }); });

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

Событие нажатия на кнопку "Страница 1" обрабатывается функцией $("#btn1").click(), а событие нажатия на кнопку "Страница 2" обрабатывается функцией $("#btn2").click().

Содержимое файлов page1.html и page2.html, которые загружаются в область контента динамически, представляет собой простые HTML-страницы или текстовые файлы с контентом.

Скачать исходные файлы примера (18,4 кб):

Пример 3. Отправка данных на сервер в фоновом режиме и получение контента

Рассмотрим пример, отправляющий введенное имя пользователя на сервер. Сервер при получении имени выдает приветствие и подсчитывает количество символов в введенном имени.

Содержимое файла index.html.

Введите имя:


$(document).ready(function(){ $("#myForm").submit(function(){ $.ajax({ type: "POST", url: "greetings.php", data: "username="+$("#username").val(), success: function(html){ $("#content").html(html); } }); return false; }); });

В теле документа создана форма для ввода имени пользователя. И контейнер для загрузки динамического контента.

Заметим, что сама форма не имеет привычных полей action и method. В качестве обработчика события нажатия на кнопку "Отправить", выступает функция $("#myForm").submit(). Рассмотрим эту функцию.

$("#myForm").submit(function(){ $.ajax({ type: "POST", url: "greetings.php", data: "username="+$("#username").val(), success: function(html){ $("#content").html(html); } }); return false; });

Как мы видим, основная работа опять связана с функцией $.ajax(). В этот раз появляются дополнительные параметры, не рассмотренные в примерах 1 и 2. А именно:

Type: "POST" Тип передачи данных. data: "username="+$("#username").val() Параметры, передаваемые серверу. В данном случае мы передаем содержимое поля username - имя пользователя. В общем случае, параметры записываются также, как в методе GET, одной строкой, например:
data: "username=Vasya&age=18&sex=male"

Обратим внимание, что в конце написана строка:

Return false; Это сделано для того, чтобы форма не пыталась передать данные файлу, из которого она запускается и не происходило перезагрузки страницы.

Содержимое файла greetings.php.

Выводим на экран приветствие и подсчитываем количество символов в имени.

Скачать исходные файлы примера (16,8 кб):

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

1. На страницах с динамическим обновлением контента, кнопка "Назад" в браузере не работает корректно.

2. Страницы с динамическим обновлением контента не меняют URL, в зависимости от своего содержимого, поэтому не могут быть добавлены в закладки.

3. Страницы с динамическим обновлением контента не индексируются поисковыми системами, т.к. они не выполняют команды JavaScript.

От приведенных недостатов можно избавиться программным путем. В данной статье такие способы не рассматриваются.

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

Надеюсь, она будет полезна для понимания, что такое AJAX и с чем его едят.

Что такое AJAX ? Пример реализации.

AJAX, или, более длинно, A synchronous J avascript A nd X ml - технология для взаимодействия с сервером без перезагрузки страниц.

За счет этого уменьшается время отклика и веб-приложение по интерактивности больше напоминает десктоп.

Технология AJAX, как указывает первая буква A в ее названии - асинхронна, т.е браузер, отослав запрос, может делать что угодно, например, показать сообщение
об ожидании ответа, прокручивать страницу, и т.п.

Вот код кнопки в примере выше:

При нажатии она вызывает функцию vote , которая отправляет запрос на сервер, ждет ответа, а затем показывает сообщение об этом в div "е под кнопкой:

Здесь будет ответ сервера

Для обмена данными с сервером используется специальный объект XmlHttpRequest , который умеет отправлять запрос и получать ответ с сервера. Кроссбраузерно создать такой объект можно, например, так:

Function getXmlHttp(){ var xmlhttp; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!="undefined") { xmlhttp = new XMLHttpRequest(); } return xmlhttp; }

Более подробно о деталях реализации AJAX с использованием XmlHttpRequest и других транспортов можно почитать в разделе про общение с сервером .

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

// javascript-код голосования из примера function vote() { // (1) создать объект для запроса к серверу var req = getXmlHttp() // (2) // span рядом с кнопкой // в нем будем отображать ход выполнения var statusElem = document.getElementById("vote_status") req.onreadystatechange = function() { // onreadystatechange активируется при получении ответа сервера if (req.readyState == 4) { // если запрос закончил выполняться statusElem.innerHTML = req.statusText // показать статус (Not Found, ОК..) if(req.status == 200) { // если статус 200 (ОК) - выдать ответ пользователю alert("Ответ сервера: "+req.responseText); } // тут можно добавить else с обработкой ошибок запроса } } // (3) задать адрес подключения req.open("GET", "/ajax_intro/vote.php", true); // объект запроса подготовлен: указан адрес и создана функция onreadystatechange // для обработки ответа сервера // (4) req.send(null); // отослать запрос // (5) statusElem.innerHTML = "Ожидаю ответа сервера..." }

Поток выполнения, использованный vote, довольно типичен и выглядит так:

  • Функция создает объект XmlHttpRequest
  • назначает обработчик ответа сервера onreadystatechange
  • открывает соединение open
  • отправляет запрос вызовом send (ответ сервера принимается срабатывающей в асинхронном режиме функцией onreadystatechange)
  • показывает посетителю индикатор состояния процесса
  • Серверный обработчик, к которому обращен AJAX-запрос (в примере это vote.php) по сути ничем не отличается от обычной страницы. AJAX-запрос, отправляемый XmlHttpRequest , ничем не отличается от обычного запроса.

    Просто текст, который возвращает сервер, не показывается как HTML, а читается и обрабатывается функцией onreadystatechange .

    Смысл AJAX - в интеграции технологий

    Технология AJAX использует комбинацию:

    • (X)HTML, CSS для подачи и стилизации информации
    • DOM-модель, операции над которой производятся javascript на стороне клиента, чтобы обеспечить динамическое отображение и взаимодействие с информацией
    • XMLHttpRequest для асинхронного обмена данными с веб-сервером. В некоторых AJAX-фреймворках и в некоторых ситуациях, вместо XMLHttpRequest используется IFrame, SCRIPT-тег или другой аналогичный транспорт.
    • JSON часто используется для обмена данными, однако любой формат подойдет, включая форматированный HTML, текст, XML и даже какой-нибудь EBML

    Типичное AJAX-приложение состоит как минимум из двух частей.

    Первая выполняется в браузере и написана, как правило, на JavaScript, а вторая - находится на сервере и написана, например, на Ruby, Java или PHP .

    Между этими двумя частями происходит обмен данными через XMLHttpRequest(или другой транспорт).

    Что я могу сделать с помощью AJAX ?

    Смысл AJAX - в интерактивности и быстром времени отклика.

    Небольшие элементы управления

    В первую очередь AJAX полезен для небольших элементов, связанных с элементарными действиями: добавить в корзину, подписаться, и т.п.

    Динамическая подгрузка данных с сервера.

    Например, дерево, узлы которого подгружаются по мере раскрытия.

    На момент его появления он явился единственным открытым почтовым сервисом, использующим AJAX для следующих фич.

    • Проверка ошибок ввода формы ДО сабмита

      На сервер передается имя пользователя, результат проверки возвращается на страницу.

    • "Мгновенная" загрузка

      Браузер обращается к серверу только за данными, а не обновляет весь громоздкий интерфейс

    • Автоматическая "доставка" писем в открытую папку

      Время от времени отправляется запрос на сервер и, если пришли новые письма, они появляются в браузере.

    • Автодополнение

      Достаточно ввести первые буквы имени адресата, и остальные дополняются автоматически, как в десктоп-приложениях.

    Результат: обширная популярность, высокий спрос на account"ы с момента открытия.

    Синхронная модель VS Асинхронная модель

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

    Условно говоря, мы действуем так:

  • закидываем удочку
  • ждем, когда клюнет
  • клюнуло - включаем подтяжку спиннинга
  • При асинхронном подходе мы:

  • вешаем на удило специальный детектор клева, задаем ему тянуть спиннинг, когда клюнет
  • закидываем удочку
  • занимаемся другими делами
  • детектор клева срабатывает, запуская подтяжку спиннинга
  • Т.е, в синхронном случае удочка постоянно приковывает наше внимание. Ловля рыбы - последовательный процесс.

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

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

    Существуют приемы, облегчающие асинхронное программирование, например, отложенный объект Deferred (Twisted,Dojo,Mochikit), но об этом - в отдельной статье.

    Синхронная и асинхронная модель в AJAX

    Вернемся к нашим баранам: браузеру, серверу и, скажем, базе данных.

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

    Все процессы выполняются последовательно, один за другим.

    Сетевые задержки включены во время ожидания, обозначенное на схеме серым цветом.

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

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

    Здесь сервер сразу же уведомляет браузер о том, что запрос принят в обработку и освобождает его для дальнейшей работы. Когда ответ будет готов - сервер перешлет его, и на браузере будет вызвана соответствующая функция показа, но пока этот ответ формируется и пересылается - браузер свободен.

    Пользователь может написать комментарии, заполнить и отослать форму и т.п: Могут производиться новые асинхронные запросы.

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

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

    Особенно в случае нескольких одновременных асинхронных запросов, нужно заботиться об очередности выполнения и ответа (race-conditions) и, в случае ошибки, оставлять приложение в целостном (consistent) состоянии.

    Особенности асинхронной модели
    • Сложность в реализации
      • Недостаточные возможности браузера (javascript)
      • Асинхронная модель сложнее для отладки
    • Race conditions
      • Неопределена последовательность выполнения
      • Можно делать много одновременных задач ("удочек"), но задача, начатая первой, может окончиться последней.
    • Реакция тут же, но неизвестно, какой будет результат. Усложнена обработка ошибок
      • Ошибок коммуникации - разрыв связи, и т.п.
      • Пользовательских ошибок - например, не хватило привилегий
    • Контроль целостности (bugproof)
      • Например, редактор отправил асинхронный запрос на удаление ветки дерева. Добавление в нее нужно отключить, пока не придет ответ сервера. Если вдруг не хватило привилегий, то операция не удалась.
    • Интерактивность
    • Быстрый интерфейс

    Плюсов всего два, зато какие! Овчинка стоит выделки.

    Асинхронный drag"n"drop.

    Иногда для асинхронных операций необходимо делать различные "финты ушами". Например, хочется сделать drag"n"drop в дереве, т.е перетаскивать статьи из одного раздела в другой мышкой, и чтобы они на сервере в базе данных меняли родителя.

    Drag"n"drop - это "взял мышей объект - положил куда надо - готово". Но в асинхронной модели не может быть все прям сразу "готово".
    Надо проверить привилегии на сервере, проверить, существует ли еще объект, вдруг его удалил другой пользователь.

    Надо как-то показать, что процесс пошел, но результат "ща будет..". А как? В асинхронной модели указатель мыши не может просто так зависнуть над объектом, превратившись в часики.

    В таком случае применяют либо синхронные запросы к серверу - и тогда все действительно подвисает, либо оригинальный выход - положить объект, как будто он перенесен, и проинформировать анимированной иконкой об ожидании ответа.
    Если ответ отрицателен - обработчик ответа переносит объект обратно.

    Stale context, устаревший контекст

    В примере с drag"n"drop также затронута проблема "stale context" - устаревшего контекста.

    Веб - многопользовательская среда. Если для навигации используется,
    скажем, дерево статей, то над ним работают много человек. Один из них может удалить ветку дерева, над которой работает другой: конфликт.

    Как правило, для преодоления таких казусов используются следующие средства:

    Политика редактирования

    Это когда все знают кто чего делает и на уровне деления полномочий и личного общения такие удаления согласовывают. Вариант заведомо небезопасный, но обычно работающий.

    Локинг и/или версионный контроль

    Локинг - блокирование редактируемых документов.

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

    Более подробно о локинге и версионности можно почитать, например, в документации к системе версионного контроля Subversion .

    Автообновление контекста

    Проблема устаревшего контента может быть на 99% решена при помощи мгновенного автообновления.

    Браузер держит постоянное соединение с сервером (или делает время от времени корректирующие запросы) - и нужные изменения отсылаются по этому каналу.

    Например, в раскрытую ветку дерева иногда подгружаются новые статьи, в открытый почтовый интерфейс - новые письма.

    Вообще, проблема устаревшего контекста напрямую относится к задаче целостности данных. За конечную проверку целостности, как и при валидации форм, в любом случае несет ответственность сервер.



    Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: