GoogleBot поддерживает асинхронные запросы с помощью XMLHttpRequest


Содержание материала:

Объект XMLHttpRequest

Объект XMLHttpRequest (или, сокращенно, XHR) дает возможность браузеру делать HTTP-запросы к серверу без перезагрузки страницы.

Несмотря на слово XML в названии, XMLHttpRequest может работать с данными в любом текстовом формате, и даже бинарными данными. Использовать его очень просто.

Кроссбраузерное создание объекта запроса

В зависимости от браузера, код для создания объекта может быть разный. Кроссбраузерная функция создания XMLHttpRequest:

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

Использование XMLHTTPRequest

Различают два использования XmlHttpRequest. Первое — самое простое, синхронное.

Синхронный XMLHttpRequest

Здесь сначала создается запрос, задается открытие (open) синхронного соединение с адресом /xhr/test.html и запрос отсылается с null, т.е без данных: send(null).

При синхронном запросе браузер «подвисает» и ждет на строчке 3, пока сервер не ответит на запрос. Когда ответ получен — выполняется строка 4, код ответа сравнивается с 200 (ОК), и при помощи alert печатается текст ответа сервера. Все максимально просто.

Свойство responseText получит такой же текст страницы, как браузер, если бы Вы в перешли на /xhr/test.html. Для сервера GET-запрос через XmlHttpRequest ничем не отличается от обычного перехода на страницу.

Асинхронный XMLHttpRequest

Асинхронность включается третьим параметром функции open. В отличие от синхронного запроса, функция send() не останавливает выполнение скрипта, а просто отправляет запрос.

Запрос req регулярно отчитывается о своем состоянии через вызов функции req.onreadystatechange. Состояние под номером 4 означает конец выполнения, поэтому функция-обработчик при каждом вызове проверяет — не настало ли это состояние.

Вообще, список состояний readyState такой:

Состояния 0-2 вообще не используются.

Вызов функции с состоянием Interactive в теории должен происходить каждый раз при получении очередной порции данных от сервера. Это могло бы быть удобным для обработки ответа по частям, но Internet Explorer не дает доступа к уже полученной части ответа.
Firefox дает такой доступ, но для обработки запроса по частям состояние Interactive все равно неудобно из-за сложностей обнаружения ошибок соединения. Поэтому Interactive тоже не используется.

На практике используется только последнее, Complete.

Если хотите углубиться в тонкости багов браузеров c readyState, отличными от 4, то многие из них рассмотрены в статье на Quirksmode (англ.).

Не используйте синхронные запросы

Синхронные запросы применяются только в крайнем случае, когда кровь из носу необходимо дождаться ответа сервера до продолжения скрипта. В 999 случаях из 1000 можно использовать асинхронные запросы. При этом общий алгоритм такой:

  1. Делаем асинхронный запрос
  2. Рисуем анимированную картинку или просто запись типа «Loading. «
  3. В onreadystatechange при достижении состояния 4 убираем Loading и, в зависимости от status вызываем обработку ответа или ошибки.

Кроме того, иногда полезно ставить ограничение на время запроса. Например, хочется генерировать ошибку, если запрос висит более 10 секунд.

Для этого сразу после send() через setTimeout ставится вызов обработчика ошибки, который очищается при получении ответа и обрывает запрос с генерацией ошибки, если истекли 10 секунд.

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

Этот пример демонстрирует такой таймаут.

Методы объекта XMLHttpRequest

Первый параметр method — HTTP-метод. Как правило, используется GET либо POST, хотя доступны и более экзотические, вроде TRACE/DELETE/PUT и т.п.

URL — адрес запроса. Можно использовать не только HTTP/HTTPS, но и другие протоколы, например FTP и FILE://. При этом есть ограничения безопасности, так называемая «same origin policy»: запрос со страницы можно отправлять только на тот домен и порт, с которого она пришла.

Ниже это ограничение и способы обхода будут рассмотрены подробнее.

async = true задает асинхронные запросы, эта тема была поднята выше.

userName, password — данные для HTTP-авторизации.

Отсылает запрос. Аргумент — тело запроса. Например, GET-запроса тела нет, поэтому используется send(null) , а для POST-запросов тело содержит параметры запроса.

abort()

Вызов этого метода req.abort() обрывает текущий запрос.

Здесь есть одно НО для браузера Internet Explorer. Успешный вызов abort() на самом деле может не обрывать соединение, а оставлять его в подвешенном состоянии на некоторый таймаут (20-30 секунд). Отловить такие повисшие соединения можно через прокси для отладки, например, Fiddler.

У браузера есть лимит: не более 2 одновременных соединений с одним доменом-портом. Т.е, если два соединения уже висят (и отвиснут по таймауту), то третье открыто не будет, пока одно из них не умрет. Надеюсь, Вы с такой проблемой не столкнетесь. Ее можно обойти использованием кросс-доменных XmlHttpRequest.

setRequestHeader(name, value)

getAllResponseHeaders()

getResponseHeader(headerName)

Свойства объекта XMLHttpRequest

onreadystatechange

readyState

responseText

responseXML

Ответ сервера в виде XML, при readyState=4.

Это свойство хранит объект типа XML document, с которым можно обращаться так же, как с обычным document. Например,

Чтобы браузер распарсил ответ сервера в свойство responseXML, в ответе должен быть заголовок Content-Type: text/xml.
Иначе свойство responseXML будет равно null.

status

Для HTTP-запросов — статусный код ответа сервера: 200 — OK, 404 — Not Found, и т.п. Браузер Internet Explorer может также присвоить status код ошибки WinInet, например 12029 для ошибки «cannot connect».

Запросы по протоколам FTP, FILE:// не возвращают статуса, поэтому нормальным для них является status=0.

statusText

Текстовая расшифровка status, например «Not Found» или «OK».

GET и POST-запросы. Кодировка.

При отправке обычной формы, браузер сам кодирует значения полей и составляет тело GET/POST-запроса. При работе через XmlHttpRequest, это нужно делать самим, в коде. Большинство проблем и вопросов здесь связано с непониманием, где и какое кодирование нужно осуществлять.

Есть два вида кодирования запроса. Первый — это метод GET и POST-формы с кодировкой urlencoded, она же — кодировка по умолчанию. В браузере они определяются как:

При таком способе кодировки (urlencoded) название и значение каждой переменной кодируется функцией encodeURIComponent. Формируя XmlHttpRequest, мы должны делать то же самое «руками». Конечно, только с теми переменными, в которых могут быть спецсимволы или не английские буквы, т.е которые и будут как раз закодированы.

В методе POST параметры передаются не в URL, а в теле, посылаемом через send() . Поэтому params нужно указывать не в адресе, а при вызове send()

Кроме того, при POST обязателен заголовок Content-Type, содержащий кодировку. Это указание для сервера — как обрабатывать (раскодировать) пришедший запрос.

Заголовки Content-Length, Connection в POST-запросах, хотя их и содержат некоторые «руководства», обычно не нужны. Используйте их, только если Вы действительно знаете, что делаете.

Запросы multipart/form-data

Второй способ кодирования — это отсутствие кодирования. Например, это нужно для пересылки файлов. Он указывается в форме (только для POST) так:

В этом случае ничего не кодируется. А сервер, со своей стороны, посмотрев на Content-Type(=multipart/form-data), поймет, что пришло.

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

Кодировка

Если Вы используете только UTF-8 — пропустите эту секцию.

Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8. Не в кодировке страницы, а именно в UTF-8. Поэтому, например, в PHP их нужно при необходимости перекодировать функцией iconv.

С другой стороны, когда ответ с сервера браузер воспринимает в той кодировке, которая указана в заголовке ответа Content-Type. Т.е, опять же, в PHP, чтобы браузер воспринял ответ в windows-1251 и нормально отобразил данные на странице в windows-1251, нужно послать заголовок в php-коде самим, типа:

Или же, это должен сделать сервер. Например, в apache автоматически добавляется кодировка опцией:

Частые проблемы

Кеширование

Многие браузеры поддерживают кеширование ответов на XmlHttpRequest запросы. При этом реализации кеширования немного разные.

Например, при повторном XmlHttpRequest на тот же URL, Firefox посылает запрос с заголовком «If-Modified-Since» со значением, указанным в заголовке «Last-Modified» предыдущего ответа.

А Internet Explorer делает так, только когда кешированный ответ устарел, т.е после времени из заголовка «Expires» предыдущего ответа. Поэтому, кстати, многие думают, что Internet Explorer вообще не очищает кеш ответов.

Самое простое решение проблемы — просто убрать кеширование. Например, при помощи заголовков, или добавлением случайного параметра в URL типа:

Есть, однако, ряд случаев, когда кеширование XMLHttpRequest браузером полезно, улучшает время ответа и экономит трафик.

Пример демонстрирует универсальный код работы с кешем для Internet Explorer и Firefox.

В Internet Explorer, если запрос возвращается из кеша без перепроверки, заголовок Date — пустая строка. Поэтому нужно сделать дополнительный запрос, который на самом деле никакой не дополнительный, т.к текущий возвращен из кеша.

Ссылку на кешированый запрос сохраняем, т.к если код ответа дополнительного запроса — «304 Not Modified», то его тело станет пустой строкой («»), и нужно будет вернуться к кешированному объекту. Более эффективным, впрочем, будет не создавать новый объект XmlHttpRequest, а сохранить данные из существующего и использовать заново его же.

Пример выше опирается на то, что сервер всегда выдает заголовок «Date», что верно для большинства конфигураций. В нем делается синхронный запрос. В асинхронном случае, проверка на Date и т.д нужно делать после получения ответа в функции-обработчике onreadystate.

Повторное использование объекта XmlHttpRequest

В Internet Explorer, если open() вызван после установки onreadystatechange, может быть проблема с повторным использованием этого XmlHttpRequest.

Чтобы использовать заново XmlHttpRequest, сначала вызывайте метод open(), а затем — присваивайте onreadystatechange. Это нужно потому, что IE неявно очищает объект XmlHttpRequest в методе open(), если его статус «completed».

Вызывать abort() для перенаправления запроса на другой URL не нужно, даже если текущий запрос еще не завершился.

Утечки памяти

В Internet Explorer объект XmlHttpRequest принадлежит миру DOM/COM, а Javascript-функция — миру Javascript. Вызов req.onreadystatechange = function() < . >неявную круговую связь: req ссылается на функцию через onreadystatechange, а функция, через область видимости — видит (ссылается на) req.

Невозможность обнаружить и оборвать такую связь во многих (до IE 6,7 редакции июня 2007?) версиях Internet Explorer приводит к тому, что XmlHttpRequest вместе с ответом сервера, функция-обработчик, и всё замыкание прочно оседают в памяти до перезагрузки браузера.

Чтобы этого избежать, ряд фреймворков (YUI, dojo. ) вообще не ставят onreadystatechange, а вместо этого через setTimeout проверяют его readyState каждые 10 миллисекунд. Это разрывает круговую связку req onreadystatechange, и утечка памяти не грозит даже в самых глючных браузерах.

Ограничения безопасности. Кросс-доменный XMLHttpRequest

Для ограничения XmlHttpRequest используется философия «Same Origin Policy». Она очень проста — каждый сайт в своей песочнице. Запрос можно делать только на адреса с тем же протоколом, доменом, портом, что и текущая страница.

Топ-пост этого месяца:  Присущие CSS проблемы и способы их решения специфичность стилей, неявняе проценты и другие сложности

Т.е, со страницы на адресе http://site.com нельзя сделать XmlHttpRequest на адрес https://site.com, http://site.com:81 или http://othersite.com

Это создает проблему, если хочется взять контент с другого сайта. Как правило, в этом случае вместо XmlHttpRequest используются другие средства, например, загрузка через динамически создаваемый тег

Лекции по веб-программированию

Технология Ajax

AJAX (от англ. Asynchronous Javascript and XML — «асинхронный JavaScript и XML») — подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером. В результате, при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся быстрее и удобнее.

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

Обычные (классические) веб страницы, (которые не используют AJAX) должны быть перезагружены полностью при необходимости обновить содержимое.

История

Впервые термин AJAX был публично использован 18 февраля 2005 года в статье Джесси Джеймса Гарретта (Jesse James Garrett) «Новый подход к веб-приложениям»[3]. Гарретт придумал термин, когда ему пришлось как-то назвать новый набор технологий, предлагаемый им клиенту.

Однако в той или иной форме многие технологии были доступны и использовались гораздо раньше, например в подходе «Remote Scripting», предложенном компанией Microsoft в 1998 году, или с использованием HTML-элемента IFRAME, появившегося в Internet Explorer 3 в 1996 году.

AJAX стал особенно популярен после использования его компанией Google в сервисах Gmail, Google Maps и Google Suggest.

Принцип работы

AJAX имеет вид всего лишь одного объекта под названием XMLHttpRequest.

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

Когда Вы используете Ajax нужно учитывать следующие правила: Вся информация передается/получается исключительно в кодировке UTF-8; В разных браузерах XMLHttpRequest вызывается по-разному.

Преимущества

Экономия трафика. Передаются данные только конкретной части страницы, что существенно снижает трафик.

Уменьшение нагрузки на сервер. Нет надобности обновлять страницу целиком, уходит конкретный запрос. Например, Вы захотели проголосовать на сайте. После нажатия кнопки отправляются данные на сервер по Вашему голосу, и возвращается ответ. При этом сама страница не обновляется. Меняется только результат.

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

Разнообразие в использовании. Действие AJAX подразумевает под собой не только работу с формами. Например, в поиске Google вы можете видеть подборку поисковых фраз после ввода уже первых букв Вашего запроса.

Недостатки

Требуется включенный Java Script. Если в настройках безопасности браузера будет выключен Java Script, то результата работы AJAX можно не увидеть.

Данные не доступны поисковикам. Что логично, динамически изменяемые данные, как и прочие в Java Script не видимы поисковым роботом.

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

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

Методы и свойства объекта XMLHttpRequest

Методы

abort() — отмена текущего запроса к серверу.

getAllResponseHeaders() — получить все заголовки ответа от сервера.

getResponseHeader(«имя_заголовка») — получить указаный заголовок.

open(«тип_запроса»,«URL»,«асинхронный»,«имя_пользователя»,«пароль») — инициализация запроса к серверу, указание метода запроса. Тип запроса и URL — обязательные параметры. Третий аргумент — булево значение. Обычно всегда указывается true или не указывается вообще (по умолчанию — true). Четвертый и пятый аргументы используются для аутентификации (это очень небезопасно, хранить данные об аутентификации в скрипте, так как скрипт может посмотреть любой пользователь).

send(«содержимое») — послать HTTP запрос на сервер и получить ответ.

setRequestHeader(«имя_заголовка»,«значение») — установить значения заголовка запроса.

Свойства

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

readyState — номер состояния запроса. От 0 до 4:

0 — Объект не инициализирован.

1 — Объект загружает данные.

2 — Объект загрузил свои данные.

3 — Объек не полностью загружен, но может взаимодействовать с пользователем.

4 — Объект полностью инициализирован; получен ответ от сервера.

responseText — представление ответа сервера в виде обычного текста (строки). Полный текст есть только при readyState=4, ряд браузеров дают доступ к полученной части ответа сервера при readyState=3.

responseXML — объект документа, совместимый с DOM, полученного от сервера.

status — состояние ответа от сервера. Например, для HTTP-запросов — статусный код ответа сервера: 200 — OK, 404 — Not Found, и так далее. Запросы по протоколам FTP, FILE:// не возвращают статуса, поэтому нормальным для них является status=0.

statusText — текстовое представление состояния ответа от сервера. Например, Not Found или OK.

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

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

Теперь создаем функцию для отправки запроса

GoogleBot поддерживает асинхронные запросы с помощью XMLHttpRequest

Современные веб-приложение, как правило, разделяются на две части: клиент и сервер. Клиент представляет собой веб-страницу с кодом JavaScript. К серверным технологиям относятся PHP, Ruby, Node.js, ASP.NET и т.д., которые получают запрос от клиента, обрабатывают и отправляют в ответ результат обработки.

Ajax представляет технологию для отправки запросов к серверу из клиентского кода JavaScript без перезагрузки страницы. Сам термин расшифровывается как Asynchronous JavaScript And XML. То есть изначально AJAX предполагал асинхронное взаимодействие клиента и сервера посредством данных в формате XML. Хотя сейчас XML во многом вытеснил формат JSON. В любом случае AJAX революционизировал веб-среду, позволив создавать динамичные отзывчивые веб-приложения.

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

Объект XMLHttpRequest

Для создания приложений, использующих Ajax, применяются различные способы. Но самым распространенным способом является использование объекта XMLHttpRequest :

После создания объекта XMLHttpRequest можно отправлять запросы к серверу. Но для начала надо вызвать метод open() для инициализации:

Метод open() принимает три параметра: тип запроса (GET, POST, HEAD, PUT), адрес запроса и третий необязательный параметр — логическое значение true или false, указывающее, будет ли запрос осуществляться в асинхронном режиме. То есть в данном случае запрос будет иметь тип GET, он будет направляться по адресу «http://localhost/hello.txt в синхронном режиме, так как стоит значение false (для асинхронного режима указывается значение true).

Синхронный и асинхронный режим отличаются тем, что запрос в синхронном режиме пока запрос не выполнится, остальной код javascript не может выполняться. По умолчанию, если третий параметр не используется, то запрос отправляется в асинхронном режиме, что позволяет параллельно с выполнением запроса выполнять также и другой код javascript. И в большинстве случаев, как правило, используется именно асинхронный режим.

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

После инициализации запроса методом open() необходимо отправить запрос с помощью метода send() :

Свойства XMLHttpRequest

Объект XMLHttpRequest имеет ряд свойств, которые позволяют проконтролировать выполнение запроса:

status : содержит статусный код ответа HTTP, который пришел от сервера. С помощью статусного кода можно судить об успешности запроса или об ошибках, которые могли бы возникнуть при его выполнении. Например, статусный код 200 указывает на то, что запрос прошел успешно. Код 403 говорит о необходимости авторизации для выполнения запроса, а код 404 сообщает, что ресурс не найден и так далее.

statusText : возвращает текст статуса ответа, например, «200 OK»

responseType : возвращает тип ответа. Есть следующие типы:

Асинхронный запрос в цикле XMLHttpRequest неправильная работа

Javascript
Javascript
Javascript

Javascript
Javascript

При выполнении скрипта результат выдается только для последнего элемента массива, а нужно для всех.
Что пробовал?:
Менял местами пункты 1 и 2. — не помогло
Пробовал использовать вместо iObject.onreadystatechange — iObject.onload — не помогло
Что дальше делать ума не приложу, мозг уже дымится, прошу вашей помощи.

Javascript
Javascript
04.02.2020, 01:04

XMLHttpRequest запрос
Ситуация следующая. Есть сервер VPS, на котором стоит приложение Node.js. К нему необходимо.

XMLHttpRequest не отправляет запрос
Всем привет. Есть у меня простая задачка, с помощью VK api вытащить инфу о пользователе и.

Сделать XMLHttpRequest запрос на http
Всем привет. Ситуация такая: Есть один сайт А с которого делает XMLHttpRequest запрос на сайт В у.

Кросс-доменный XMLHttpRequest запрос
После GET запроса, Не удаётся прочесть ответ сервера, т.к. сервер не добавляет заголовок.

Не могу сделать запрос XMLHttpRequest (POST)
Подскажите рабочий пример POST запроса, ничего не нашел, другие примеры пробовал — они не работают.

04.02.2020, 04:20 2

Колбэки, переданные в setTimeout помещаются в специальную очередь — callback Queue (структура типа First In First Out).
Функции из этой очереди будут выполнены только после выполнения всего синхронного кода.

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

04.02.2020, 06:18 3

setTimeOut здесь роли не играет, но он всё по делу сказал.
При вызове функции run() происходит следующее:
1. Итерация цикла, в которой ты глобально объявляешь переменные iObject , http(или они уже задекларированы заранее) проделываешь необходимые присваивания и задаешь callback для onreadystatechange.
2. iObject.send(); — Асинхронно осуществляешь запрос.
3. JS не ждёт выполнения запроса, соответственно продолжает выполнять код, делает все проверки, удаляет объект iObject.
Начинает следующую итерацию цикла, идём к пункту 1.

Всё это происходит всего 3 раза, в этот момент все 3 асинхронных запроса уже выполнено. JS начинает эти коллбеки выполнять — все они обращаются к iObject, но он удалён. Если его не удалять каждую итерацию — он будет содержать в себе только ответ последнего запроса. И счётчик показывает тебе всегда i=3, потому что цикл весь уже выполнен.

Решения: добавить для iObject.open(‘GET’, http); третий параметр false для синхронного выполнения, тогда нужно отказаться от коллбэка и обрабатывать запрос сразу после iObject.send.

Либо обернуть содержимое цикла в функцию, которая обеспечит через замыкание уникальность объекта iObject

JavaScript — Синхронный AJAX запрос (XMLHttpRequest)

Урок, в котором на простых примерах разберем, как работать с технологией AJAX, а именно познакомимся с тем как с помощью объекта XMLHttpRequest (сокращённо XHR) создавать синхронные HTTP-запросы к серверу и получать от него ответы.

Основы AJAX

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

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

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

  1. Получение некоторой информации (данных) со страницы или формы (при необходимости)
  2. Отправление запрос на веб-сервер
  3. Получение ответа с веб-сервера
  4. Отображение результатов на странице, если ответ был успешен.

Основы создания синхронных AJAX запросов

Пример 1. Выполнение синхронного AJAX запроса

Рассмотрим пример выполнения синхронного AJAX запроса к серверу с помощью метода XMLHttpRequest. В данном примере запросим данные, находящиеся в файле data.txt на сервере и отобразим их на странице в элементе span .

Пример будет состоять из файлов index.html , script.js и data.txt , которые для простоты можно расположить на сервере в одном каталоге.

Начнём разработку с создания HTML-страницы, к которой подключим файл script.js . Этот файл, а точнее его содержимое будет выполнять всю основную работу. Но перед тем как перейти к его разработке, создадим на станице элементы div и span . Элемент div будет играть роль кнопки, при нажатии на которую будет выполняться AJAX запрос. А элемент span будет играть роль контейнера, который будет содержать ответ, пришедший с сервера.

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

После этого откроем файл data.txt и введём в него текст «Привет, мир!». Сохраним и закроем файл.

И наконец, перейдём к созданию файла script.js . Содержимое этого файла будет выполнять все основные действия, т.е. отправлять ajax запрос на сервер, принимать от сервера ответ и обновлять содержимое страницы (помещать ответ в элемент span ).

Рассмотрим создание данного файла поэтапно:

Получим элемент на событие click которого необходимо подписаться.

Подпишемся на событие click элемента с помощью метода addEventListener .

Создадим переменную request , которая будет содержать экземпляр объекта XMLHttpRequest .

Настроим HTTP-запрос к серверу с помощью метода open. Данный метод имеет 3 основных параметра. 1 параметр отвечает за метод, с помощью которого мы отправляем данные на сервер. Различают два основных метода: GET и POST. Метод GET передаёт данные в составе URL после знака ? (для отделения данных используется амперсанд & ).

Метод POST передаёт данные в теле HTTP-запроса.

2 параметр отвечает за адрес (URL), по которому посылается запрос. А 3 параметр определяет тип запроса: синхронный ( false ) или асинхронный ( true ).

Отправляем ajax запрос на сервер.

После отправки синхронного запроса на сервер, наша страница замораживается (т.е. не отвечает на запросы пользователя) и ждёт ответа от сервера. Как только ответ приходит, он становится доступным в виде следующих свойств объекта XMLHttpRequest :

status (статус запроса). Если значение свойства равно 200, то запрос выполнен успешно. Если в status хранится другое число, значит, запрос завершился с ошибкой (например, 404, 500 и т.д.)

responseText – содержит текст ответа, который пришёл от сервера. Т.е. данное свойство всегда содержит то, что нам нужно, если статус ответа был 200.

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

Просмотр объекта XMLHttpRequest в консоли браузера

Получаем результат и отображаем его на странице.

Пример 2. Обработка синхронного AJAX запроса на сервере с помощью PHP

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

В данном примере страница будет состоять из 3 кнопок. Первая кнопка будет иметь текст 1, вторая кнопка текст 2 и третья кнопка текст 3. При нажатии на любую из кнопок будет выполняться синхронный запрос на сервер. В качестве метода передачи запроса будем использовать GET. А адрес, по которому будем посылать запрос и параметры ajax.php . Получать данные отправленные клиентом на сервере будем с помощью GET-переменной HTTP ($_GET). После этого полученные данные будем обрабатывать на сервере, и возвращать клиенту ответ (строку).

Пример 3. Передача синхронного AJAX запроса на сервер с помощью метода POST

В этом примере данные на сервер будем передавать с помощью метода POST (в теле HTTP-запроса). В методе POST данные (параметры) передаются не в составе URL (метод GET), а в теле, которое мы посылаем серверу через send() . Т.е. для того чтобы передать данные с помощью POST, мы их должны поместить в качестве параметра методу send() . Кроме того, при отправке данных с помощью POST необходимо также указать заголовок Content-Type, содержащий кодировку с помощью которой мы зашифровали данные. Это необходимо сделать для того чтобы сервер знал как обработать (расшифровать), пришедшие к нему данные (запрос).

# Получаем данные в Javascript с помощью XMLHttpRequest

Я очень часто вижу, что люди используют $http в Angular или jQuery или другие библиотеки и даже не знают, что выполняется внутри и как в чистом javascript работать с http запросами.

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

Именно на этой технологии работают все современные Single Page приложения.

Для этого используется XMLHttpRequest. Из его названия можно подумать, что он может работать только с xml, но это не так. Он может работать с любыми данными.

Для того, чтобы обращатся на сервер за данными, давайте создадим API с тестовыми данными с помощью сервиса mocky.io.

Вот у меня есть JSON данных

Вставляем его в body запроса и в advance mode выбираем

Для того, чтобы любой домен мог обращатся к этому API.

Нажимаем Generate response и получаем ссылку на наш API.

Теперь давайте писать javascript.

Для начала нам нужно создать новый екземпляр XMLHttpRequest.

Теперь сконфигурировать какой url мы хотим получить

Для этого на xhr мы вызываем метод open передавая туда тип запроса, url, и асинхронный ли запрос. Конечно мы хотим асинхронный. Никогда не используйте синхронные запросы, так как это блокирует продолжение скрипта. В 99 случаях из 100 этого делать не нужно.

Не стоит думать, что xhr.open выполняет запрос. Хотя из названия похоже. Он его только конфигурирует. Для отправки запроса используется xhr.send

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

Внутри метода мы должны проверять readyState на 4, чтобы понять, когда запрос закончится. Пока readyState ниже четверки, то запрос не закончен. Там происходит начало запроса, получение заголовкой, загрузка body и только потом запрос завершен.

Теперь давайте добавим проверку на error и вывод результатов в консоль

Как мы видим, результат выводится в виде строки, поэтому нам нужно еще и парсить его в JSON

Какие же основные минусы XMLHttpRequest и почему все используют ajax в jQuery для получения данных или отдельные библиотеки для этого например superagent или axios.

Первым минус — это конечно количество кода. В любой из вспомогательных библиотек метод для работы с http запросами намного лаконичнее.

Второй — это отсутствие промисов при работе с XMLHttpRequest. Мы не можем написать .then, передать туда коллбек и выполнить что мы хотим когда запрос завершится. Поэтому с этим кодом неудобно работать.

Третий — это кроссбраузерность. Даже в IE 10-11 XMLHttpRequest работает не так, как в других браузерах.

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

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

JavaScript метод XMLHttpRequest.send()

Определение и применение

JavaScript метод send() объекта XMLHttpRequest позволяет отправить запрос на сервер.

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

Для того, чтобы отправить запрос его необходимо изначально инициализировать с использованием метода open() объекта XMLHttpRequest .

Если заголовок Accept не был установлен с помощью метода setRequestHeader() объекта XMLHttpRequest , то отправляется заголовок Accept с типом «*/* » (любой тип).

Поддержка браузерами

Метод Chrome

Firefox Opera Safari IExplorer Edge
send() Да Да Да Да Да Да

JavaScript синтаксис:

Cпецификация

Значения параметров

Параметр Описание
body Представляет из себя тело данных для отправки в запросе XHR . Если метод запроса соответствует значению » GET » или » HEAD «, то этот параметр игнорируется и тело запроса имеет значение null . Необязательный параметр.

Исключения

Тип исключения Описание
InvalidStateError Возникает в том случае, если метод send() уже был вызван для запроса, и / или запрос завершен.
NetworkError Возникает в том случае, если тип ресурса, который нужно извлечь, является Blob , и метод не соответствует типу » GET «.

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

В следующем примере мы рассмотрим с вами как отправить » GET » запрос с использованием метода send() объекта XMLHttpRequest .

В этом примере с использованием атрибута событий onclick при нажатии на кнопку (HTML элемент ) вызываем функцию getPhone, которая:

  • Вызывает конструктор объекта XMLHttpRequest и инициализирует переменную новым объектом этого типа.
  • С помощью метода open() объекта XMLHttpRequest определяем параметры для запроса — указываем, что HTTP запрос будет осуществлен методом » GET «, а в качестве URL адреса на который будет отправлен запрос мы задаем файл формата json . Обратите внимание, что файл размещен на том же сервере и в том же каталоге, что и документ с которого выполняется скрипт. Файл имеет следующий вид:
  • С помощью метода send() объекта XMLHttpRequest отправляем запрос на сервер.
  • С использованием обработчика событий onreadystatechange , вызываемого при запуске события readystatechange , то есть при каждом изменении свойства readyState объекта XMLHttpRequest мы вызываем функцию, которая проверяет состояние запроса, оно должно соответствовать значению 4 (операция полностью завершена) и числовой код состояния HTTP ответа должен соответствовать значению 200 (успешный запрос). Если условия выполнены, то с использованием метода JSON.parse() анализируем строку в формате JSON и инициализируем переменную значением, полученным в ходе анализа. После этого с помощью метода getElementById() находим элемент с определенным глобальным атрибутом id и изменяем его содержимое значением ключа объекта, содержащегося в инициализированной ранее переменной.

Результат нашего примера:

Пример использования методов open() и send() объекта XMLHttpRequest

В следующем примере мы рассмотрим с вами как отправить » POST » запрос с использованием метода send() объекта XMLHttpRequest .

В этом примере с использованием атрибута событий onsubmit, установленного на форму (HTML элемент ) при нажатии на кнопку (HTML элемент ) вызываем функцию logIn(), которой мы передаем объект события (объект Event ) и она в свою очередь:

  • С помощью метода preventDefault() объекта Event отменяет действие события по умолчанию. Это необходимо для того, чтобы избежать перезагрузки страницы во время отправки формы.
  • Инициализирует четыре переменные: первая и вторая содержат значения полей , третья содержит строковое значение, которое мы будем отправлять на сервер в качестве тела данных в запросе (состоит в том числе из первых двух переменных), четвертая вызывает конструктор объекта XMLHttpRequest и инициализирует переменную новым объектом этого типа.
  • С помощью метода open() объекта XMLHttpRequest определяем параметры для запроса — указываем, что HTTP запрос будет осуществлен методом » POST «, а в качестве URL адреса на который будет отправлен запрос мы задаем файл формата php . Обратите внимание, что файл размещен на том же сервере и в том же каталоге, что и документ с которого выполняется скрипт. Файл содержит следующий простой скрипт на языке программирования PHP:
  • С помощью метода setRequestHeader() объекта XMLHttpRequest задаем значение заголовка HTTP запроса (указываем, что передаваемое значение на сервер кодируется в кортежах с ключом, разделенных символоми ‘&’ , с ‘=’ между ключом и значением).
  • С помощью метода send() объекта XMLHttpRequest отправляем запрос на сервер. Обратите внимание, что мы в качестве параметра метода передаем переменную, которая содержит сформированное выше строковое значение.
  • С использованием обработчика событий onreadystatechange , вызываемого при запуске события readystatechange , то есть при каждом изменении свойства readyState объекта XMLHttpRequest мы вызываем функцию, которая проверяет состояние запроса, оно должно соответствовать значению 4 (операция полностью завершена) и числовой код состояния HTTP ответа должен соответствовать значению 200 (успешный запрос). Если условия выполнены, то с помощью метода getElementById() находим элемент с определенным глобальным атрибутом id и изменяем его содержимое значением, содержащим ответ сервера на запрос в виде текста (значение свойства responseText).

Результат нашего примера:

Пример использования методов send() и setRequestHeader() объекта XMLHttpRequest JavaScript XMLHttpRequest

Поймать асинхронную сетевую ошибку из XMLHttpRequest send()

Я делаю http-запрос с использованием экземпляра XMLHttpRequest xhr . Я открываю его в асинхронном режиме:

Когда я хочу что-то отправить:

Он выдает следующую ошибку, когда сервер не работает:

Как я могу поймать и обработать эту ошибку, когда я делаю запрос асинхронно? Стандарт

используйте событие onerror XMLHttpRequest():

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

сначала обнаруживает, когда сеть доступна или нет с этой функцией

second создайте свой HTTP-запрос, который будет использоваться ниже.

Теперь послушайте свой запрос с помощью этой функции function networkOrFail (callFunc, callTime) <

Объект XMLHttpRequest

Мы начали изучать HTML5 с возможностей маркировки, таких как семантические элементы, веб-формы и видео. Но по мере овладения материалом мы постепенно перешли на программирование веб-страниц HTML5 с использованием JavaScript. А теперь мы затронем новые возможности HTML5, которые выводят веб-программирование на новый уровень.

Для этих возможностей требуется не только применение JavaScript, но и немного помощи со стороны серверных программ. Серверная программа — это программа, которая исполняется на сервере и может быть на любом из языков серверного программирования.

Добавление в наш инструментарий серверного программирования представляет небольшую проблему. С одной стороны, выбор языка серверного программирования не имеет значения при условии, что он может работать с чисто HTML5-страницами (а все эти языки могут). Но с другой стороны, бессмысленно влезать по уши в изучение новой технологии, которую вы не планируете использовать или которая не поддерживается вашим веб-хостом. А хороших языков серверного программирования предостаточно, включая PHP, ASP.NET, Ruby, Java, Python и многие другие.

Но прежде чем мы начнем изучать новые возможности HTML5 в области взаимодействия с сервером, нам нужно знать, каковой была ситуация в этой области раньше. Это означает изучение важного JavaScript-объекта XMLHttpRequest, посредством которого веб-страницы могут взаимодействовать с веб-сервером. Этому объекту и посвящена данная статья, новые же возможности HTML5 (серверные события и веб-сокеты) рассматриваются в следующих статьях.

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

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

Объект XMLHttpRequest является идеальным инструментом для получения данных с веб-сервера. Далее приведено несколько примеров данных, которые можно получить с веб-сервера посредством этого объекта:

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

Данные, которые можно вычислить только на сервере. Например, веб-сайт может содержать на сервере программу, выполняющую сложные вычисления. Эти вычисления можно было бы попытаться выполнить в браузере с помощью JavaScript, но по разным причинам это может оказаться невозможным.

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

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

Лучший способ разобраться с объектом XMLHttpRequest — это начать экспериментировать с ним. Этим мы и займемся в последующих разделах, рассмотрев два простых примера.

Отправка запроса веб-серверу

На рисунке показана веб-страница, которая просит веб-сервер выполнить простое математическое вычисление. Этот запрос отправляется веб-серверу посредством объекта XMLHttpRequest:

По нажатию кнопки «Спросить у сервера» веб-страница создает объект XMLHttpRequest и отправляет два числа на веб-сервер. Веб-сервер отрабатывает простой сценарий, выполняющий математическую операцию над числами, и отправляет ответ обратно на веб-страницу.

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

Создание сценария

Сценарий PHP создается в простом текстовом файле (WebCalculator.php) и имеет следующую структуру:

Для данного примера код для выполнения вычисления и предоставления результатов донельзя простой и выглядит так:

Даже если вы и не эксперт по PHP, у вас, скорее всего, не будет трудностей разобраться, что этот код делает. Первым делом мы получаем два числа, отправленные веб-страницей. Знак доллара ($) обозначает переменную, поэтому код создает две переменные: $num1 и $num2. Значения для переменных код извлекает из встроенной в PHP коллекции, называющейся $_GET. Эта коллекция содержит всю информацию из URL, посредством которой был запрошен данный сценарий.

Например, если поместить сценарий PHP в файл WebCalculator.php, строка с запросом этого сценария будет выглядеть так:

В данном случае URL содержит две единицы информации в конце (в части URL, называющейся строкой запроса — query string). Значение первой переменной в этой части, number1, равно 34, а второй, number2, равно 58. Начало строки запроса обозначается знаком вопроса (?), а каждая последующая переменная — знаком амперсанда (&).

Когда код PHP начинает исполняться, он извлекает эту информацию из URL и сохраняет ее в коллекции $_GET, где она доступна для последующих операций. (Большинство платформ серверного программирования поддерживает модель, подобную этой. Например, в технологии ASP.NET эта информация сохраняется в коллекции Request.QueryString.)

Ветераны HTML знают, что данные на веб-сервер можно отправлять двумя способами — посредством строки запроса или вставкой их в тело запроса. В любом случае данные кодируются одинаково, и доступ к ним на сервере предоставляется похожим образом. Например, в PHP данные, переданные в теле запроса, помещаются в коллекцию $_POST.

Получив эти два числа, сценарий PHP просто суммирует их. Последний шаг — отправить результаты назад веб-странице, которая подала запрос. Эти результаты можно было бы обернуть в разметку HTML или даже в приспособленную для данных разметку XML, но это будет слишком. Для данного примера, и простого текста будет вполне достаточно. Но независимо от выбранного формата данных, все, что требуется для их отправки — это простая PHP-команда echo.

Итак, сценарий состоит из всего четырех строк PHP-кода. Но этого достаточно, чтобы установить основной шаблон: веб-страница задает веб-серверу вопрос, а веб-сервер предоставляет ответ на этот вопрос.

Простота вычислений в данном примере может породить вопрос: нельзя ли выполнить их полностью в браузере посредством JavaScript, а не прибегать к помощи сервера? Конечно же, можно. Но в данном случае важно не собственно вычисление. Рассмотренный сценарий PHP служит примером для выполнения любой задачи, которую нужно выполнить на сервере. Вычисления могут быть любой сложности, но базовый образец обмена данными будет тем же.

Обращение к веб-серверу

Вторым шагом будет создание страницы, которая с помощью объекта XMLHttpRequest использует сценарий PHP. Структура страницы показана ниже:

Код начинается достаточно просто. Сначала создается объект XMLHttpRequest для использования во всех функциях:

GoogleBot поддерживает асинхронные запросы с помощью XMLHttpRequest

Современные веб-приложение, как правило, разделяются на две части: клиент и сервер. Клиент представляет собой веб-страницу с кодом JavaScript. К серверным технологиям относятся PHP, Ruby, Node.js, ASP.NET и т.д., которые получают запрос от клиента, обрабатывают и отправляют в ответ результат обработки.

Ajax представляет технологию для отправки запросов к серверу из клиентского кода JavaScript без перезагрузки страницы. Сам термин расшифровывается как Asynchronous JavaScript And XML. То есть изначально AJAX предполагал асинхронное взаимодействие клиента и сервера посредством данных в формате XML. Хотя сейчас XML во многом вытеснил формат JSON. В любом случае AJAX революционизировал веб-среду, позволив создавать динамичные отзывчивые веб-приложения.

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

Объект XMLHttpRequest

Для создания приложений, использующих Ajax, применяются различные способы. Но самым распространенным способом является использование объекта XMLHttpRequest :

После создания объекта XMLHttpRequest можно отправлять запросы к серверу. Но для начала надо вызвать метод open() для инициализации:

Метод open() принимает три параметра: тип запроса (GET, POST, HEAD, PUT), адрес запроса и третий необязательный параметр — логическое значение true или false, указывающее, будет ли запрос осуществляться в асинхронном режиме. То есть в данном случае запрос будет иметь тип GET, он будет направляться по адресу «http://localhost/hello.txt в синхронном режиме, так как стоит значение false (для асинхронного режима указывается значение true).

Синхронный и асинхронный режим отличаются тем, что запрос в синхронном режиме пока запрос не выполнится, остальной код javascript не может выполняться. По умолчанию, если третий параметр не используется, то запрос отправляется в асинхронном режиме, что позволяет параллельно с выполнением запроса выполнять также и другой код javascript. И в большинстве случаев, как правило, используется именно асинхронный режим.

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

После инициализации запроса методом open() необходимо отправить запрос с помощью метода send() :

Свойства XMLHttpRequest

Объект XMLHttpRequest имеет ряд свойств, которые позволяют проконтролировать выполнение запроса:

status : содержит статусный код ответа HTTP, который пришел от сервера. С помощью статусного кода можно судить об успешности запроса или об ошибках, которые могли бы возникнуть при его выполнении. Например, статусный код 200 указывает на то, что запрос прошел успешно. Код 403 говорит о необходимости авторизации для выполнения запроса, а код 404 сообщает, что ресурс не найден и так далее.

statusText : возвращает текст статуса ответа, например, «200 OK»

responseType : возвращает тип ответа. Есть следующие типы:

Топ-пост этого месяца:  Урок 15. Angular 4 NgRx. Эффекты
Добавить комментарий