Полный ajax. теория и примеры. фишки и фичи

Код jQuery

Вот что делает наш код jQuery — он  получает информацию для элемента выбора в виде JSON с сервера, генерирует разметку HTML и устанавливает обработчики событий для отслеживания изменений. Если элемент выбора меняется, то процесс повторяется с новыми пунктами.

В коде используется две функции JavaScript:

  • refreshSelects запускает плагин Chosen и привязывает обработчики событий каждый раз, когда новый пункт добавляется на страницу;
  • fetchSelect запрашивает фид JSON с сервера и генерирует разметку для ответа.

assets/js/script.js

$(function(){
	
	var questions = $('#questions');
	
	function refreshSelects(){
		var selects = questions.find('select');
		
		// Улучшаем элемент selects с помощью плагина Chose
		selects.chosen();
		
		// Ждем изменений
		selects.unbind('change').bind('change',function(){
			
			// Выбранная опция
			var selected = $(this).find('option').eq(this.selectedIndex);
			// Ищем атрибут data-connection
			var connection = selected.data('connection');
			
			
			// Удаляем следующий контейнер li (к=если есть)
			selected.closest('#questions li').nextAll().remove();
			
			if(connection){
				fetchSelect(connection);
			}

		});
	}
	
	var working = false;
	 
	function fetchSelect(val){
		
		if(working){
			return false;
		}
		working = true;
		
		$.getJSON('ajax.php',{key:val},function(r){
			
			var connection, options = '';
			
			$.each(r.items,function(k,v){
				connection = '';
				if(v){
					connection = 'data-connection="'+v+'"';
				}
				
				options+= '<option value="'+k+'" '+connection+'>'+k+'</option>';
			});
			
			if(r.defaultText){
				
				// Плагин Chose требует, чтобы был добавлен пустой элемент опции
				// если нужно выводить текст "Пожалуйста, выберите"
				
				options = '<option></option>'+options;
			}
			
			// Строим разметку для раздела select
			
			$('<li>\
				<p>'+r.title+'</p>\
				<select data-placeholder="'+r.defaultText+'">\
					'+ options +'\
				</select>\
				<span class="divider"></span>\
			</li>').appendTo(questions);
			
			refreshSelects();
			
			working = false;
		});
		
	}
	
	$('#preloader').ajaxStart(function(){
		$(this).show();
	}).ajaxStop(function(){
		$(this).hide();
	});
	
	// В начале загружаем выбор продукта
	fetchSelect('productSelect');
});

Отлично! Теперь осталось сделать генерацию фида JSON

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

Вот как выглядит простой ответ из нашего скрипта PHP:

{
    "items": {
        "Телефоны": "phoneSelect",
        "Ноутбуки": "notebookSelect",
        "Планшеты": ""
    },
    "title": "Что желаете купить?",
    "defaultText": "Выберите категорию продукта"
}

Функция fetchSelect проходит циклом все пункты и использует ключи как содержание элементов опций, а значения — как указатели на следующие пункты. Выбор пунктов «Телефоны» и «Ноутбуки» в данном примере будет приводить к генерации новых элементов выбора, а пункта «Планшеты» — нет.

Настройка базовых параметров Ajax-запросов

Существует группа параметров, с помощью которых можно выполнить базовую настройку Ajax-запроса (некоторые из них, url и type, мы рассмотрели выше). Из всех доступных параметров они представляют наименьший интерес, и их имена в основном говорят сами за себя. Параметры, о которых идет речь, приведены в таблице ниже:

Базовые конфигурационные параметры Ajax-запроса
Параметр Описание
accepts Устанавливает для запроса значение заголовка Accept, который указывает MIME-типы, поддерживаемые браузером. По умолчанию это значение определяется параметром dataType
cache Значение false указывает на то, что содержимое запроса не должно кэшироваться сервером. По умолчанию кешируются все типы данных, кроме script и jsonp
contentType Устанавливает для запроса значение заголовка content-туре
dataType Указывает, какие типы данных ожидаются от сервера. Если используется этот параметр, то jQuery будет игнорировать информацию, предоставляемую сервером о типе запроса
headers Задает дополнительные заголовки и значения, которые должны включаться в запрос
jsonp Задает строку, которую следует использовать вместо функции обратного вызова при выполнении запросов JSONP (кроссдоменные запросы). Этот параметр требует согласования с сервером
jsonpCallback Задает имя функции обратного вызова, которое должно использоваться вместо автоматически сгенерированного случайного имени, используемого jQuery по умолчанию
password Задает пароль, который должен использоваться в запросе при прохождении процедуры аутентификации
scriptCharset Указывает jQuery, какой набор символов используется при кодировании запрашиваемого JavaScript-содержимого
timeout Задает длительность тайм-аута (в миллисекундах) для запроса
userName Задает имя пользователя, которое должно использоваться в запросе при прохождении процедуры аутентификации

Задание тайм-аутов и заголовков

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

В этом примере параметр timeout устанавливает максимальную длительность тайм-аута, равную 5 сек. Если запрос за это время не будет выполнен, то вызовется функция, заданная с помощью параметра error, и будет выведен код ошибки, определяемый параметром status.

Таймер запускается сразу же после передачи запроса браузеру, и большинство браузеров налагают ограничения на количество одновременно выполняющихся запросов. Это означает, что существует риск того, что к моменту истечения тайм-аута запрос даже не будет запущен. Чтобы избежать этого, необходимо располагать сведениями об ограничениях браузера, а также об объеме и ожидаемой длительности любых других выполняющихся Ajax-запросов.

Дополнительно в этом примере ниже используется параметр headers, с помощью которого в запрос добавляется заголовок. Для указания заголовков используется объект отображения данных. Используемый здесь заголовок может быть полезным для создания веб-приложений, поддерживающих архитектурный стиль REST, если только сервер правильно его распознает.

Объект jqXHR

Метод ajax() возвращает объект jqXHR, который можно использовать для получения подробной информации о запросе и с которым можно взаимодействовать. Объект jqXHR представляет собой оболочку объекта XMLHttpRequest, составляющую фундамент браузерной поддержки Ajax.

При выполнении большинства операций Ajax объект jqXHR можно просто игнорировать, что я и рекомендую делать. Этот объект используется в тех случаях, когда необходимо получить более полную информацию об ответе сервера, чем та, которую удается получить иными способами. Кроме того, его можно использовать для настройки параметров Ajax-запроса, но это проще сделать, используя настройки, доступные для метода ajax(). Свойства и методы объекта jqXHR описаны в таблице ниже:

Свойства и методы объекта jqXHR
Свойство/метод Описание
readyState Возвращает индикатор хода выполнения запроса на протяжении всего его жизненного цикла, принимающий значения от 0 (запрос не отправлен) до 4 (запрос завершен)
status Возвращает код состояния HTTP, отправленный сервером
statusText Возвращает текстовое описание кода состояния
responseXML Возвращает ответ в виде XML (если он является XML-документом)
responseText Возвращает ответ в виде строки
setRequest(имя, значение) Возвращает заголовок запроса (это можно сделать проще с помощью параметра headers)
getAllResponseHeaders() Возвращает в виде строки все заголовки, содержащиеся в ответе
getResponseHeaders(имя) Возвращает значение указанного заголовка ответа
abort() Прерывает запрос

Объект jqXHR встречается в нескольких местах кода. Сначала он используется для сохранения результата, возвращаемого методом ajax(), как показано в примере ниже:

В этом примере мы сохраняем результат, возвращаемый методом ajax(), а затем используем метод setInterval() для вывода информации о запросе каждые 100 мс

Использование результата, возвращаемого методом ajax(), не изменяет того факта, что запрос выполняется асинхронно, поэтому при работе с объектом jqXHR необходимо соблюдать меры предосторожности. Для проверки состояния запроса мы используем свойство readyState (завершению запроса соответствует значение 4) и выводим ответ сервера на консоль

Для данного сценария консольный вывод выглядит так (в вашем браузере он может выглядеть несколько иначе):

Я использую объект jqXHR лишь в редких случаях и не делаю этого вообще, если он представляет собой результат, возвращаемый методом ajax(). Библиотека jQuery автоматически запускает Ajax-запрос при вызове метода ajax(), и поэтому я не считаю возможность настройки параметров запроса сколько-нибудь полезной. Если я хочу работать с объектом jqXHR (как правило, для получения дополнительной информации об ответе сервера), то обычно делаю это через параметры обработчика событий, о которых мы поговорим далее. Они предоставляют мне информацию о состоянии запроса, что избавляет от необходимости выяснять его.

Необходимые файлы и папки

3.1 Файловая структура

  • app/
    • assets/
      • css/
      • js/
        • bootbox.min.js
        • jquery.min.js
    • products/
      • create-product.js
      • delete-product.js
      • read-products.js
      • read-one-product.js
      • update-product.js
    • app.js
  • index.html

3.3 Подключение Bootstrap

Как вы можете видеть из файла index.html, мы включили Bootstrap через CDN.

Если вам нужно включить Bootstrap через загрузку, то это будет работать также.

3.4 Создание главного CSS файла

  1. Создайте в корне папку app
  2. В ней создайте папку assets
  3. В папке assets создайте папку css
  4. В папке css создайте файл style.css

Файл style.css — это наш главный файл CSS. Вы можете поместить в этот файл любой CSS для дополнительной стилизации веб-страницы. В нашем случае у нас есть следующий код CSS внутри файла style.css.

3.5 Установка JavaScript-библиотек jQuery и Bootbox.js

Откройте папку assets в папке app и создайте папку js

В папку js мы поместим библиотеки jQuery и Bootbox.js.

Библиотека jQuery необходима, чтобы сделать наше простое приложение простым. Скачайте jQuery по этой ссылке.

Библиотека Bootbox.js необходима, чтобы диалоговое окно подтверждения «удаления» выглядело лучше. Загрузите Bootbox.js по этой ссылке.

Также есть CDN для этих JavaScript библиотек. Вы можете использовать их, если хотите. Оба варианта будут работать.

3.6 Создание файла app.js

Файл app.js будет содержать некоторые основные функции HTML и JavaScript, которые могут использоваться другими JS файлами в нашем приложении.

В папке app создайте файл app.js со следующим содержимым.

3.7 Создание папки «products» и файлов для будущих скриптов

Теперь мы создадим несколько JavaScript файлов.

  1. Внутри папки app создайте папку products
  2. В папке products создайте следующие файлы:
  • read-products.js
  • create-product.js
  • read-one-product.js
  • update-product.js
  • delete-product.js

Пока мы оставим их пустыми. Но мы заполним их в следующих разделах этого руководства.

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

До сих пор мы рассматривали примеры использования $.get() только для отправки запросов на сервер, игнорируя любой ответ, который может сформировать скрипт на серверной стороне. Но в большинстве случаев ваш JavaScript код будет ожидать ответ от скрипта на серверной стороне и обрабатывать полученные данные.

AJAX запрос — асинхронный , что означет его выполнение в фоновом режиме, когда остальной код JavaScript продолжает действовать. Как же в таком случае получать ответ от сервера, когда завершится запрос?

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

Как только возвратная функция создана, вы можете передать ее в качестве третьего аргумента в метод $.get() :

Загрузка разметки на страницу с помощью метода load()

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

В простейшем случае вы можете вызвать метод следующим образом:

$('#myElement').load( url );

Данный пример делает запрос AJAX по адресу , получает разметку с сервера и замещает ею содержание элемента  .

Также можно передать данные в запросе, также как и в методах и :

var data = { city: "Васюки", date: "20120318" };
$('#myElement').load( url, data );

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

<h2>Прогноз погоды в Васюках</h2>
<h3>18 марта 2012</h3>
<p>Будет мерзко холодно, сыро и слякотно. Макисмальная температура: 1C.</p>

имитирует эффект выполнения скрипта на стороне сервера и возвращает разметку с прогнозом погоды.

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

<!doctype html>
<html lang="ru">
<head>
<title>Прогноз погоды</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
 
<script>
 
  $( function() {
 
    $('#getForecast').click( function() {
      var data = { city: "Васюки", date: "20120318" };
      $('#forecast').load( "getForecast.html", data );
    } );
 
  } );
 
</script>
 
</head>
 
<body>
 
<button id="getForecast">Получить прогноз погоды</button>
<div id="forecast"></div>
 
</body>
</html>

Пробуем запустить демонстрацию и наслаждаемся результатом работы запроса AJAX.

Вот как работает код примера:

  1. Страница содержит элемент с идентификатором , в котором будет размещаться разметка прогноза.
  2. Обработчик события для кнопки формирует данные для отправки на сервер.
  3. Затем обработчик выбирает и вызывает метод jQuery , передавая URL  () и объект с данными.
  4. jQuery выполняет AJAX  запрос к файлу . Когда браузер получает ответ , jQuery автоматически замещает содержание элемента полученной разметкой.

Одной из причин того, что метод легко использовать является то, что не нужно писать возвратную функцию для обработки ответа — jQuery все делает для вас. Но если вам требуется производить какие-нибудь действия после того, как разметка вставлена, вы можете передать «полноценную» возвратную функцию в качестве третьего аргумента  методу .

Optional parameters

In addition to the row’s data, DataTables can use the following optional parameters on each individual row’s data source object to perform automatic actions for you:

Parameter name Type Description
Set the ID property of the node to this value
Add this class to the node
Add the data contained in the object to the row using the jQuery method to set the data, which can also then be used for later retrieval (for example on a click event).
Add the data contained in the object to the row node as attributes. The object keys are used as the attribute keys and the values as the corresponding attribute values. This is performed using using the jQuery method. Please note that this option requires DataTables 1.10.5 or newer.

Использование вспомогательных методов для работы с конкретными типами данных

Библиотека jQuery предоставляет три вспомогательных метода, которые делают работу с некоторыми типами данных более удобной. Некоторые из них мы рассмотрим далее.

Получение HTML-фрагментов

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

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

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

Получение и выполнение сценариев

Метод getScript() загружает файл JavaScript, а затем выполняет содержащиеся в нем инструкции. Чтобы продемонстрировать работу этого метода, я создал файл myscript.js и сохранил его вместе с файлом test.html на своем веб-сервере. Содержимое этого файла представлено в примере ниже:

Эти инструкции генерируют три ряда элементов, описывающих цветы. Мы обошлись здесь без определения шаблонов и использовали циклы для генерации элементов (хотя, вообще говоря, следовало бы воспользоваться шаблонами данных).

Самое важное, что необходимо знать при работе со сценариям, — между инициализацией Ajax-запроса и выполнением инструкций сценария состояние документа может измениться. В примере ниже приведен сценарий из основного документа, в котором по-прежнему используется метод getScript(), но при этом, еще до завершения Ajax-запроса, модифицируется дерево DOM:. Здесь мы вызываем метод getScript() для основной функции $() и передаем ему в качестве аргумента URL-адрес файла, который хотим использовать

Если сервер способен предоставить указанный файл и этот файл содержит действительный JavaScript-код, то последний будет выполнен

Здесь мы вызываем метод getScript() для основной функции $() и передаем ему в качестве аргумента URL-адрес файла, который хотим использовать. Если сервер способен предоставить указанный файл и этот файл содержит действительный JavaScript-код, то последний будет выполнен.

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

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

В данном примере после запуска Ajax-запроса с помощью метода getScript() из документа удаляется элемент row2, для чего используется метод remove(). Данный элемент используется в файле myscript.js для вставки новых элементов. Эти элементы отбрасываются незаметным для пользователя образом, поскольку в документе селектору #row2 ничто не соответствует. Итоговый результат представлен на рисунке:

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

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

Для загрузки данных JSON с сервера предназначен метод getJSON(). Возможно, это наименее полезный из всех трех вспомогательных методов, поскольку он не делает с данными ничего сверх того, что делает базовый метод get().

Объяснение примера — функция showCustomer()

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

Функция showCustomer

function showCustomer(str) {  var xhttp;   if (str == «») {   
document.getElementById(«txtHint»).innerHTML = «»;   
return;  }  xhttp = new XMLHttpRequest(); 
xhttp.onreadystatechange = function() {    if (this.readyState
== 4 && this.status == 200) {    document.getElementById(«txtHint»).innerHTML
= this.responseText;    }  };  xhttp.open(«GET»,
«getcustomer.php?q=»+str, true);  xhttp.send();}

Функция выполняет следующие действия:

Проверить, выбран ли клиент
Создать объект XMLHttpRequest
Создайте функцию, которая будет выполняться, когда будет готов ответ сервера
Отправьте запрос в файл на сервере
Обратите внимание, что к URL адресу добавлен параметр (q) (с содержимым раскрывающегося списка)

Try it Yourself Examples in Every Chapter

In every chapter, you can edit the examples online, and click on a button to
view the result.

HTML Page

<!DOCTYPE html><html>
<body>
<div id=»demo»>  <h2>Let AJAX change this text</h2> 
<button type=»button» onclick=»loadDoc()»>Change Content</button>
</div>
</body>
</html>

The HTML page contains a <div> section and a <button>.

The <div>
section is used to display information from a server.

The <button> calls a function (if it is clicked).

The function requests data from a web
server and displays it:

Function loadDoc()

function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {   
if (this.readyState == 4 && this.status == 200) {    
document.getElementById(«demo»).innerHTML = this.responseText;   
}  };  xhttp.open(«GET», «ajax_info.txt», true); 
xhttp.send();
}

«ajax_info.txt» looks like this:

<h1>AJAX</h1><p>AJAX is not a programming language.</p><p>AJAX is a
technique for accessing web servers from a web page.</p><p>AJAX stands for
Asynchronous JavaScript And XML.</p>

What is AJAX?

AJAX = Asynchronous JavaScript And
XML.

AJAX is not a programming language.

AJAX just uses a combination of:

  • A browser built-in XMLHttpRequest object (to request data from a web server)
  • JavaScript and HTML DOM (to display or use the data)

AJAX is a misleading name. AJAX applications might use XML to transport data,
but it is equally common to transport data as plain text or JSON text.

AJAX allows web pages to be updated asynchronously by exchanging data with a web server behind the scenes.
This means that it is possible to update parts of a web page, without reloading the whole page.

How AJAX Works

  • 1. An event occurs in a web page (the page is loaded, a button is clicked)
  • 2. An XMLHttpRequest object is created by JavaScript
  • 3. The XMLHttpRequest object sends a request to a web server
  • 4. The server processes the request
  • 5. The server sends a response back to the web page
  • 6. The response is read by JavaScript
  • 7. Proper action (like page update) is performed by JavaScript

❮ Previous
Next ❯

xmlHttpRequest

Вы знаете что такое xmlHttpRequest? XmlHttpRequest — это
объект, позволяющий браузеру делать запросы к серверу без перезагрузки
страницы. Да и это, собственно, понятно из названия: http request —
запрос по http протоколу. А вот с xml интересней: несмотря на указание
этого языка в названии, объект XHR (это сокращение от xmlHttpRequest)
работает с данными произвольного формата, не только с XML. Собственно,
технология Ajax и основана на этом компоненте. Более углублённо о нём
можно почитать на сайте xmlhttprequest.ru, посмотреть примеры
использования можно в статье о CURLe, но это нас сейчас мало интересует. Сейчас разберем Ajax с помощью JQuery.

$.ajax

Мы можем использовать метод $.ajax() несколькими путями: можем передать объект конфигурации в качестве единственного аргумента или можем передать адрес и необязательный объект конфигурации. Давайте посмотрим в первом приближении:

Конечно, вы можете быть менее многословны, просто передавая литеральный объект в метод $.ajax() и применяя анонимные функции для success и error. Такая версия проще для написания и её, вероятно, проще поддерживать:

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

В этой версии обязателен только адрес, но объект конфигурации позволяет нам сказать jQuery какие данные мы хотим передать, какой использовать метод HTTP (GET, POST и др.), какие данные мы ожидаем получить, как реагировать когда запрос успешен или нет и многое другое.

Смотрите по $.ajax() для получения полного списка параметров конфигурации.

Пример запроса GET, отправленного с помощью jQuery и Ajax

$.ajax({
    type: "GET",
    url: 'test.php',
    success: function(data){
        alert(data);
    }
});

В примере кода передаются три параметра:

  • type: тип HTTP запроса. В этом примере я отправляю запрос GET. Если вы хотите отправить запрос POST, измените “GET” на “POST”.
  • url: адрес,на который вы хотите отправить Ajax запрос. В нашем случае это страница “test.php”. Помните, что URL-адрес указывается относительно текущей страницы.
  • success: функция, которая вызывается, если запрос был успешным. Она принимает параметр data, который будет содержать вывод страницы test.php. То есть, если test.php выводит строку “OK”, то параметр data будет содержать строку “OK”.

Поэкспериментируйте с приведённым выше кодом. Например, замените“GET” на “POST” и измените URL-адрес. Можно использовать инструменты разработчика, встроенные в Firefox / Chrome для отладки Ajax- запросов. Они доступны на вкладке «Сеть». Инструменты разработчика позволяют визуализировать запрос.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector