English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Обзор технологий Ajax и Comet

Ajax - это технология, которая позволяет запрашивать дополнительные данные у сервера без перезагрузки страницы, что улучшает пользовательский опыт веб-страницы. Ядро технологии Ajax - это объект XMLHttpRequest (XHR). В этой статье мы начинаем с XHR, чтобы понять особенности технологии Ajax, а затем кратко рассмотрим технологии跨域 и Comet.

Основные методы XMLHttpRequest

Объект XHR имеет два часто используемых метода open и send. Метод open используется для запуска HTTP-запроса, но он не отправляет запрос на самом деле. Метод open принимает 3 параметра, которые представляют собой метод HTTP-запроса, URL запроса и асинхронность. Второй метод объекта XHR send используется для отправки запроса, запущенного open. Метод send принимает один параметр, представляющий собой данные的主要内容 HTTP-запроса. Если отправляется запрос GET, который не содержит данных的主要内容, то передается null. Если это запрос POST, то передается данные, которые нужно отправить. Вот пример: отправка GET-запроса к /api/data с асинхронной передачей, то есть запрос не будет блокировать выполнение других скриптов на странице.

var xhr = new XMLHttpRequest();
xhr.open("get", "/api/data", true)
xhr.send(null)

Полученные данные ответа автоматически заполняют атрибуты объекта XHR, основные из которых следующие 4:

* responseText: Текст的主要内容 ответа
* responseXML: Если тип содержимого ответа "text/xml" или "application/xml", то в этом свойстве будет содержаться XML DOM документ данных ответа
* status: HTTP-статус код ответа, обычно HTTP-статус код 200 можно рассматривать как успешный индикатор
* statusText: Объяснение HTTP-статуса

Объект XHR имеет атрибут readyState, который записывает 5 возможных состояний, через которые может пройти объект от создания до получения данных ответа:

0: Метод open() еще не вызван, запрос не инициализирован

1: Метод open() уже вызван, но метод send() еще не вызван

2: Метод send() уже вызван, но ответ еще не получен

3: Получены часть данных ответа, часть данных еще не получена

4: Получены все данные ответа, то есть ответ завершен, данные полны

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

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
 }
}
xhr.open("get", "/api/data", true)
xhr.send(null)

XHR объект предоставляет метод setRequestHeader() для установки пользовательских HTTP-заголовков запроса, который принимает два параметра: поле и значение этого поля. Установка setRequestHeader() возможна только после вызова метода open() для запуска запроса и до вызова метода send(). После получения ответа, можно получить информацию о заголовках HTTP с помощью метода getResponseHeader(), который принимает один параметр - имя поля. А getAllResponseHeaders() возвращает все заголовки в виде長ой строки. Вот простой пример.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
  console.log(xhr.getResponseHeader('SomeKey'))
  console.log(xhr.getAllResponseHeaders())
 }
}
xhr.open("get", "/api/data", true)
xhr.setRequestHeader("SomeKey", "SomeValue")
xhr.send(null)

FormData

XMLHttpRequest 2 уровня определяет тип FormData для сериализации форм, создания данных в формате формы и удобства их передачи через XHR. FormData предоставляет метод append() для прямого добавления данных, который принимает два параметра: ключ и значение. Конструктор FormData может быть вызван без параметров или с передачей одного элемента формы. После传入 элемента формы, данные этого элемента используются для предварительного заполнения ключей и значений объекта FormData. Вот простой пример.

var form = document.getElementById('myForm');
var data = new FormData(form);
data.append('someKey', 'someValue');
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 }
}
xhr.open('post', '/api/upload', true)
xhr.send(data)

Cross-Origin Resource Sharing

При реализации Ajax通信 через XHR встречается ограничение - политика безопасности границ доменов. Политика безопасности границ доменов ограничивает «одинаковые домены, одинаковые порты, одинаковые протоколы». Если XHR хочет访问 ограниченные ресурсы, возникает ошибка безопасности. CORS (Cross-Origin Resource Sharing) -资源共享 через границу доменов, его идея - использовать пользовательские HTTP заголовки для沟通 между браузером и сервером, чтобы определить успех или неудачу запроса или ответа, для реализации этого необходимо поддержка как со стороны браузера, так и сервера. В настоящее время большинство браузеров поддерживают CORS, поэтому код пишется так же, как и доступ к ресурсам в одном домене, просто URL представлен в виде абсолютного пути. Таким образом, ключевой момент для реализации доступа через границу доменов заключается в сервере, подробности реализации не рассматриваются в этой статье. Вот пример кода на前端 JavaScript.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 }
}
xhr.open('get', 'http://www.otherserver.com/api/data', true)
xhr.send(null)

JSONP

JSONP (JSON with padding) - это метод доступа к ресурсам через границу доменов с использованием JSON. JSONP состоит из двух частей: функции вызова и JSON данных. Ранее уже упоминалось, что запросы XHR могут встретить ограничения безопасности границ доменов, но тег script в HTML не имеет таких ограничений. Мы можем использовать тег script для ссылки на js файлы из других доменов. JSONP использует эту возможность, создавая динамически элемент script и направляя его src на URL другого домена, чтобы загрузить ресурсы из другого домена, а затем обрабатывать полученные данные с помощью функции вызова. Вот простой пример.

function handler(res) {
 console.log(res)
}
var script = document.createElement('script')
script.src = 'http://www.otherserver.com/api/data/?callback=handler'
document.body.insertBefore(script, document.body.firstChild)

Данный код specifies, что динамически созданный элемент script имеет src как /api/data другого домена, и указывает на функцию callback handler. После вставки script в DOM, данные будут загружены по соответствующему URL, после чего полученные данные JSON будут преобразованы в объект и вызов handler для обработки.

JSONP - это простой способ реализации доступа кcross-origin, но у него также есть некоторые安全问题, такие как получение恶意代码 от других доменов в ответ на запрос URL. У JSONP есть еще одна проблема: тег script ссылается на js, json поддерживается js, поэтому он также может быть использован для ссылок, и при запросе URL других доменов необходимо проверить, отвечает ли он в формате json, а не XML.

Comet

Ajax - это технология запроса данных от веб-страницы к серверу, а Comet является противоположной технологией, которая推送 данные от сервера к веб-странице, и рекомендуется для использования в приложениях с высокой требовательностью к времени ответа. Реализация Comet может быть произведена двумя способами: долгим опросом и потоком. Перед долгим опросом рассмотрим короткий опрос, его思路 очень проста: клиент использует таймер, который периодически отправляет запросы Ajax на сервер, чтобы проверить наличие обновленных данных, этот интервал времени обычно очень мал. Долгий опрос также заключается в постоянной отправке клиентом запросов на сервер, но в отличие от короткого опроса, клиент не должен отправлять запросы в зависимости от интервала времени, а после отправки одного запроса на сервер, соединение HTTP между клиентом и сервером поддерживается открытым до тех пор, пока сервер не будет иметь обновленных данных, которые будут отправлены через это соединение клиенту, после чего соединение HTTP закрывается. После закрытия браузер发起一个新的 связь, чтобы повторить предыдущий процесс. По сравнению с коротким опросом, долгий опрос производит меньше запросов HTTP, но длительное поддержание соединения HTTP также может занимать ресурсы сервера.

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

SSE

SSE (Server-Send Events) - это API сервера для отправки событий, который позволяет реализовать интерактивность Comet в браузере, поддерживая как опросы, так и HTTP потоки. SSE API используется для создания одностороннего соединения с сервером, через которое сервер может отправлять любое количество данных клиенту. MIME-тип ответа сервера - text/event-stream. Вот простой пример JavaScript API для SSE.

var source = new EventSource("/api/events")
source.onmessage = function(event) {
 console.log(event.data)
}

Как показано в приведенном выше коде, чтобы забронировать поток событий на сервере и получить данные, отправляемые сервером, сначала создается объект EventSource, а затем обрабатывается при наступлении события message. Данные, отправляемые сервером, хранятся в строковом формате в event.data. Объект EventSource поддерживает активное соединение с сервером, при разрыве соединения оно будет восстановлено, а чтобы действительно прервать соединение, можно вызвать метод close(). Событие message объекта EventSource срабатывает при получении нового события от сервера, кроме события message, у него есть еще два события: open и error. Событие open срабатывает при установлении соединения, а событие error срабатывает при невозможности установления соединения.

Web Sockets

Web Sockets - это канал для полнодуплексного двустороннего общения с сервером. Web Sockets не используют протокол HTTP, в то время как Ajax и Comet, о которых шла речь ранее, используют протокол HTTP. Из-за ограниченного объема статьи обсуждение Web Sockets не проводится.

Обобщение

Ajax реализует запрос данных к серверу без загрузки страницы, что улучшает пользовательский опыт веб-страницы. Реализация технологии Ajax с использованием XHR сталкивается с ограничениями политики безопасности跨域,для решения проблемы跨域问题 через CORS требуется сотрудничество как с браузером, так и с сервером. JSONP - это "маленькая хитрость" для реализации доступа кcross-домену, но также существуют некоторые проблемы. Comet расширяет Ajax, позволяя серверу推送 данные в реальном времени в браузер. С точки зрения реализации, как пинг-pong, так и HTTP-поток требуют, чтобы браузер сначала发起请求连接 к серверу. Полнодуплексное двустороннее общение через Web Sockets также имеет свои особенности, и в будущем я продолжу изучать это.

Вот и все, что есть в этой статье, я надеюсь, что содержимое статьи поможет вам в изучении или работе, и я也希望, что вы будете активно поддерживать руководства по крику!

Заявление: содержимое статьи взято из Интернета, авторские права принадлежат соответствующему автору. Контент предоставлен пользователями Интернета, загружен пользователями самостоятельно, сайт не имеет права собственности, не был отредактирован вручную и не несет ответственности за связанные с этим юридические последствия. Если вы обнаружите материалы,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма замените # на @), и предоставьте соответствующие доказательства. При подтверждении факта нарушения авторских прав сайт незамедлительно удалят涉嫌侵权的内容.

Рекомендуется для просмотра