Ajax является ключевым инструментом в современной разработке веб -приложений. Это позволяет вам асинхронно отправлять и получать данные на сервер, а затем анализировать его в JavaScript. Ajax является аббревиатурой асинхронного JavaScript и XML (асинхронный JavaScript и XML).
Имя спецификации Ajax Core унаследовано от объекта JavaScript, используемого для создания и инициации запросов: xmlhttprequest. Есть два уровня этой спецификации. Все основные браузеры реализуют первый уровень, который представляет базовый уровень функциональности. Второй уровень расширяет начальную спецификацию, включает в себя дополнительные события и некоторые функции, чтобы упростить сотрудничество с элементами форм и поддерживает некоторые связанные спецификации.
1. Аякс начинается
Ключ к Ajax лежит в объекте Xmlhttprequest, и способ понять этот объект - посмотреть на пример. Следующий код показывает простое использование объекта Xmlhttprequest:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <tite> Пример </title> </head> <body> <div> <tood> apples </button> <bute> cherries </utting> <buton> bananas </button> </div> <div = "Div> div> div> <div> <div = div> <Div> <Div =" div> <Div> <Div = " type = "Application/javascript"> var buttons = document.getElementsbytagname ("кнопка"); for (var i = 0; i <bultons.length; i ++) {кнопки [i] .onclick = handletonpress; } // Скрипт позвонит этой функции, чтобы ответить на кнопку управления элементом управления chlick function handlebuttonpress (e) {// Создать новый объект xmlhttprequest var httprequest = new xmlhttprequest (); // Установите обработчик событий для события onreadystateChange httprequest.onreadystatechange = Handleresponse; // Используйте метод Open для указания метода HTTP и URL -адреса запроса (то есть, сообщите объекту httprequest, что вы хотите сделать) httprequest.open («Get», E.Target.InnerHtml+". Html"); // здесь не отправляются данные, поэтому метод отправки не имеет доступных параметров httprequest.send (); } // Обработка ответа // Как только скрипт вызовет метод отправки, браузер отправит запрос на сервер в фоновом режиме. Поскольку запрос обрабатывается в фоновом режиме, Ajax полагается на события, чтобы информировать о ходе запроса. Function HandlerSponse (e) {// Когда запускается событие onreadyStateChange, браузер передаст объект события в указанную функцию обработчика, а свойство целевого будет установлено на XMLHTTPRequest, связанный с этим событием, если (e.Target.ReadState == xmlhttprequest.done && e.Target.StaTus == 200). document.getElementbyId ("target"). innerHtml = e.target.responsetext; // Показать содержимое запрошенного документа}} </script> </body> </html>Три дополнительная документация очень проста:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <Title> яблоки </title> <style> img {float: слева; Padding: 2px; Margin: 5px; граница: средний двойной черный; фоновый цвет: lightgrey; Ширина: 100px; высота: 100px;} </style> </head> <body> <p> <img src = "../ img/show-page/img_apples.jpg"/> страница для яблок. </p> </body> </html>Эффект показан на рисунке ниже:
Когда пользователь нажимает на каждую кнопку фруктов, браузер выполняет асинхронно и получает запрошенный документ, а основной документ не перезагружен. Это типичное поведение AJAX.
2. Использование событий Ajax
После создания и изучения простого примера вы можете начать копаться в функциях, поддерживаемых объектом xmlhttprequest и как их использовать в вашем запросе. Отправной точкой является дополнительные события, определенные в спецификации второго уровня:
Большинство из этих событий запускаются в определенный момент времени во время запроса. Два события являются исключениями, готовым StateChange и прогрессом, которые можно запустить несколько раз для предоставления обновлений прогресса.
Когда эти события запланированы, браузер использует регулярный объект события для события BeadyStateChange и объект ProgressEvent для других событий. Объект ProgressEvent определяет всех членов объекта события и добавляет эти участники, описанные на следующем рисунке:
Следующий код показывает, как использовать эти события:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> Пример </title> <style> таблица {margin: 10px; пограничная точка: collapse; float: left;} div {margin: 10px;} td, th {padding: 4px;} </style> </head> <body> <div> <tood> яблоки </button> <tutry> вишня </button> <tood> Bananas </uttoning> </div> <Таблица ID = "Events"> </table> <Div = " type = "Application/javascript"> var buttons = document.getElementsbytagname ("кнопка"); for (var i = 0; i <bultons.length; i ++) {кнопки [i] .onclick = handletonpress; } var httprequest; функция handlebuttonpress (e) {cleareventDetails (); httprequest = new xmlhttprequest (); httprequest.onreadystatechange = HandlerSponse; httprequest.onerror = handerror; httprequest.onload = handleload ;; httprequest.onloadend = handleloadend; httprequest.onloadstart = handleloadstart ;; httprequest.onprogress = handleprogress; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.send (); } function handlerSponse (e) {displayEventDetails ("readyState ("+httprequest.readystate+")") if (e.target.readystate == xmlhttprequest.done && e.target.status == 200) {document.getElementById ("target"). }} granderror (e) {displayEventDetails ("error", e);} функция HandLeLoad (e) {displayEventDetails ("Load", e);} функция HandLeLoadend (e) {DisplayEventDetails ("LoadEnd", e);} функция handleLoadend (e) e -displayEvidtails (e); HandLeLoadStart (e) {DisplayEventDetails ("LoadStart", e);} Ручка функции (e) {DisplayEventDetails ("Прогресс", e);} функция clearEventDetails () {document.getElementById ("events"). innerHtml = "<Tr> <Th> Event </th> <Th> LengthCompable </th> <Th> загружен </th> <Th> total </th>"; } функция DisplayEventDetails (eventName, e) {if (e) {document.getElementById ("events"). innerHtml+= "<tr> <td>"+eventName+"</td> <td>"+e.lengthcompatable+"</td> <td>"+e.loaded+" e.total+"</td> </tr>"; } else {document.getElementById ("Events"). innerHtml+= "<Tr> <td>"+eventName+"</td> <td> na </td> <td> na </td> <td> na </td> <td> na </td> </tr>"; }} </script> </body> </html>Это вариант предыдущего примера, регистрирующий обработчик для некоторых событий и создание записи для каждого события, обработанного в элементе таблицы. На следующем изображении вы можете увидеть, как браузер Firefox запускает эти события.
3. обрабатывать ошибки
На два типа ошибок должны быть обратное внимание при использовании AJAX. Разница между ними проистекает с разных точек зрения.
Первый тип ошибки - это проблема, наблюдаемая с точки зрения объекта xmlhttprequest: некоторые факторы предотвращают отправку запроса на сервер. Например, DNS не может разрешить имя хоста, запрос на соединение отклонено, или URL -адрес является недействительным.
Второй тип проблемы - проблема, наблюдаемая с точки зрения приложения, а не объект Xmlhttprequest. Они происходят, когда запрос успешно отправлен на сервер, который получает запрос, обрабатывает и генерирует ответ, но ответ не указывает на то, что вы ожидаете. Например, если запрашиваемый URL не существует, возникает такая проблема.
Есть три способа справиться с этими ошибками, как показано в следующем коде:
3.1 Ошибки настройки обработки
Первым типом проблемы, с которой необходимо решить, является передача неверных данных объекту Xmlhttpresquest, например, неверный URL. Они чрезвычайно склонны происходить при генерации URL -адресов на основе пользовательского ввода. Чтобы имитировать этот вид проблемы, приведенный выше документ имеет кнопку, которая добавляет плохой URL -адрес (неправильный URL). Нажатие этой кнопки вызовет метод открытия в следующей форме:
httprequest.open ("Get", "http: //")
Это ошибка, которая предотвращает выполнение запроса, и ошибка добавляется, когда такое событие происходит в объекте Xmlhttprequest. Это означает, что попытка ... оператор CHACE необходим для окружения кода, который устанавливает запрос, например,:
try {... httprequest.open ("get", "http: //") ... httprequest.send (); } catch (error) {displayerRormsg ("try/catch", erry.message)}Пункт «Улов» дает вам возможность восстановиться после ошибки. Вы можете попросить пользователя для пользователя или вернуться к URL -адресу по умолчанию или просто отказаться от запроса. В этом примере функция DisplayerRormsg вызывается для отображения сообщения об ошибке.
3.2 Ошибки запроса на обработку
Второй тип ошибки происходит, когда запрос был сгенерирован, но есть и другие ошибки. Чтобы имитировать этот тип проблемы, в примере была добавлена кнопка «Плохой хост» (хост ошибки). Когда эта кнопка нажата, метод открытия будет вызван для доступа к недоступному URL:
httprequest.open ("Get", http: //www.ycdoitt.com/nopage.html)Есть две проблемы с этим URL. Первая проблема заключается в том, что имя хоста не может быть решено с помощью DNS, поэтому браузер не может генерировать серверное соединение. Эта проблема знает, что объект xmlhttprequest становится очевидным только тогда, когда он начинает генерировать запрос, поэтому он сигнализирует об ошибках двумя способами. Если вы зарегистрируете слушатель для события ошибки, браузер отправит объект события вашему слушателю. Вот функции, используемые в примере:
Function handerror (e) {displayerRormsg ("Error Event", httprequest.status + httprequest.statustext); }Когда возникают такие ошибки, степень информации, которая может быть получена из объекта xmlhttprequest, зависит от браузера. К сожалению, в большинстве случаев будет получен статус со значением 0 и пустым значением Statastext.
Вторая проблема заключается в том, что URL и сгенерированный запрос имеют разные источники, которые не допускаются по умолчанию. Обычно вы можете отправлять запросы AJAX на тот же теолигин, который загружает сценарий. Когда браузер сообщает об этой проблеме, может быть брошена ошибка или может быть вызвано событие ошибки. Разные браузеры обрабатывают это по -разному. Различные браузеры также проверяют источник в разные моменты времени, что означает, что браузер не всегда можно увидеть, подчеркивая одну и ту же проблему. Распределение ресурсов по перекрестному происхождению может использоваться для обхода гомологичных ограничений.
3.3 Обработка ошибок приложения
Последний тип ошибки происходит, когда запрос успешно завершается (с точки зрения объекта Xmlhttprequest), но не возвращает нужные данные. Чтобы создать такие проблемы, добавьте кнопку с огурцом метки в примере выше. Нажатие этой кнопки будет генерировать URL -адрес запроса, аналогичный яблокам, вишне и бананам, но на сервере не существует документа Cucumber.html.
В самом процессе нет ошибок (поскольку запрос был завершен), и необходимо определить, что происходит на основе атрибута состояния. При запросе существующего документа будет получен код состояния 404, что означает, что сервер не может найти запрошенный документ. Вы можете увидеть, как пример обрабатывает коды статуса, отличные от 200 (то есть OK):
if (httprequest.status == 200) {target.innerhtml = httprequest.responsetext; } else {document.getElementById ("ctensityMsg"). innerhtml = "status:" + httprequest.status + "" + httprequest.statustext; }В этом примере значения статуса и statustext просто отображаются. В реальных приложениях необходимо выполнять восстановление полезной и значимым образом (например, отображение альтернативного контента или предупреждающих пользователей, что есть проблема, в зависимости от того, какой человек более подходит для приложения).
4. Получить и установить заголовки
Используя объект xmlhttprequest, вы можете установить заголовок запроса, отправленный на сервер, и заголовок в ответе сервера.
4.1 Перезаписать метод HTTP для запросов
Обычно не нужно добавлять или изменять заголовок в запросе AJAX. Браузер знает, что отправлять, и сервер знает, как ответить. Однако есть несколько исключений. Первый-это заголовок X-HTTP-Method-Override.
Стандарт HTTP часто используется для запроса и передачи HTML -документов в Интернете, и он определяет много методов. Большинство людей знают о Get and Post, потому что они наиболее широко используются. Тем не менее, существуют другие методы (включая пут и удаление), которые используются для придания значения для URL -адреса, запрашиваемого на сервер, и это использование находится на подъеме. Например, если вы хотите просмотреть запись пользователя, вы можете генерировать такой запрос:
httprequest.open ("Get", "http: // myserver/records/freeman/adam");Здесь отображаются только метод HTTP и запрошенный URL -адрес. Для этого запроса работать плавно, сторона сервера должна быть в состоянии понять запрос приложением и преобразовать его в подходящую часть данных, которые будут отправлены обратно на сервер. Если вы хотите удалить данные, вы можете написать это так:
httprequest.open (" delete ", "http: // myserver/records/freeman/adam");Ключ здесь состоит в том, чтобы выразить то, что вы хотите, чтобы сервер сделал через HTTP, а не кодировать его в URL -адрес.
Проблема с использованием методов HTTP таким образом заключается в том, что многие основные веб -технологии поддерживают только Get and Post, и многие брандмауэры только позволяют пройти только запросы GET и POST. Существует идиоматический подход, чтобы избежать этого ограничения, который состоит в том, чтобы использовать заголовок X-HTTP-Method-override, чтобы указать метод HTTP, который вы хотите использовать, но форма продается и отправляет запрос POST. Демонстрация кода заключается в следующем:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Example</title></head><body><div> <button>apples</button> <button>cherries</button> <button>bananas</button></div><div id="target">Press a button</div><script> var buttons = document.getElementsbytagname («кнопка»); for (var i = 0; i <bultons.length; i ++) {кнопки [i] .onclick = handletonpress; } var httprequest; функция handlebuttonpress (e) {httprequest = new xmlhttprequest (); httprequest.onreadystatechange = HandlerSponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setrequestheader ("x-http-method-override", "delete"); httprequest.send (); } функция handerror (e) {displayerRormsg ("Error Event", httprequest.status+httprequest.statustext); } function handleresponse () {if (httprequest.readystate == 4 && httprequest.status == 200) {document.getElementById ("target"). innerHtml = httprequest.responseText; }} </script> </body> </html>В этом примере метод SetRequestHeader на объекте Xmlhttprequest используется для указания того, что запрос хотел обрабатывать в форме метода удаления HTTP. Обратите внимание, что я установил этот заголовок только после вызова открытого метода. Если вы попытаетесь использовать метод SetRequestHeader перед методом Open, объект xmlhttprequest выбрасывает ошибку.
PS: перезапись HTTP требует, чтобы веб-прикладная плата на стороне сервера понимала соглашение о X-HTTP-метод-эверриде, и ваше приложение на стороне сервера должно быть установлено для поиска и понимания этих меньших методов HTTP.
4.2 Отключить кэширование контента
Второй полезный заголовок, который можно добавить в запросы Ajax,-это контроль за кешем, который особенно полезен при написании и отладке сценариев. Некоторые браузеры кэшируют контент, полученный с помощью запросов AJAX, и не будут запрашивать его снова во время сеанса просмотра. Для предыдущего примера это означает, что изменения на Apples.html, Cherries.html и Bananas.html не будут немедленно отражены в браузере. Следующий код показывает, как установить заголовки, чтобы избежать этого:
httprequest = new xmlhttprequest (); httprequest.onreadystatechange = HandlerSponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setrequestheader ("Контроль кэша", "без качела"); httprequest.send ();Способ установить заголовок такой же, как и в предыдущем примере, но на этот раз заголовок управляет кэшем, а желаемое значение не имеет кран. После размещения этого оператора, если контент запрашивается через изменения AJAX, оно будет отражено в следующий раз, когда будет запрошен документ.
4.3 Прочитайте заголовок ответа
Заголовок HTTP, отправленный сервером при ответе на запрос AJAX, можно прочитать через методы GetResponseHeader и GetallResponseHeaders. В большинстве случаев вам не нужно заботиться о том, что находится в заголовке, потому что они являются частью интерактивных транзакций между браузером и сервером. Следующий код показывает, как использовать это свойство:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <meta content = "width = width-width, user-scalbable = no" name = "viewport" /> <meta name = "Автор" content = "ye chaoluka" /> <meta name = "description" content "content" /" />" /> " />" /> " /> <>" /> name " /> <> name" /> <> name " /> <> name" /> <> name " /> <> name" /> <> name " /> <> natue" /> <> name " /> <> name" /> <> name " /> <> name" /> href="../img/ycdoit.ico" type="image/x-icon" rel="shortcut icon" /> <style> #allheaders,#cheader{border: medium solid black;padding: 2px;margin: 2px;} </style></head><body><div> <button>apples</button> <button>cherries</button> <Tood> бананы </button> </div> <div ID = "cheader"> </div> <div Id = "AllHeaders"> </div> <div id = "target"> нажмите кнопку </div> <script> var buttonons = document.getElementsbytagname ("кнопка"); for (var i = 0; i <bultons.length; i ++) {кнопки [i] .onclick = handletonpress; } var httprequest; функция handlebuttonpress (e) {httprequest = new xmlhttprequest (); httprequest.onreadystatechange = HandlerSponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setrequestheader ("Контроль кэша", "без качела"); httprequest.send (); } function handleresponse () {if (httprequest.readystate == 2) {document.getElementByid ("allheaders"). innerhtml = httprequest.getallresponseDehheaders (); document.getElementbyId ("cheader"). innerhtml = httprequest.getResponseHeader ("контент-тип"); } else if (httprequest.readystate == 4 && httprequest.status == 200) {document.getElementByid ("target"). innerHtml = httprequest.responsetextext; }} </script> </body> </html>Рендеринги следующие:
Согласно этому рисунку, мы видим, что программное обеспечение веб -сервера, которое работает сервер разработки, является INTELLIJ IDEA 15.0.4, и в последний раз, когда документ Apples.html был изменен 27 июня (но скриншот был 5 июля).