Xmlhttprequest

XMLHttpRequest Object Properties

Property Description
onload Defines a function to be called when the request is recived (loaded)
onreadystatechange Defines a function to be called when the readyState property changes
readyState Holds the status of the XMLHttpRequest.
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
responseText Returns the response data as a string
responseXML Returns the response data as XML data
status Returns the status-number of a request200: «OK»403: «Forbidden»404: «Not Found»
For a complete list go to the Http
Messages Reference
statusText Returns the status-text (e.g. «OK» or «Not Found»)

XMLHttpRequest Object Methods

Method Description
new XMLHttpRequest() Creates a new XMLHttpRequest object
abort() Cancels the current request
getAllResponseHeaders() Returns header information
getResponseHeader() Returns specific header information
open(method, url, async, user, psw) Specifies the requestmethod: the request type GET or POSTurl: the file locationasync: true (asynchronous) or false (synchronous)user: optional user namepsw: optional password
send() Sends the request to the serverUsed for GET requests
send(string) Sends the request to the server.Used for POST requests
setRequestHeader() Adds a label/value pair to the header to be sent

Пишем PHP-скрипт для сервера

Задача скрипта пока будет очень простой — ему нужно будет получить наши данные и показать, что всё пришло как нужно. В PHP уже встроена команда, которая разбирает JSON-строку на составляющие, поэтому весь скрипт будет занимать три строчки:

Для получения данных наш PHP-скрипт использует стандартную команду . Она просто ждёт, когда что-то прилетит, и отправляет результат в выбранную переменную. Дальше её можно разобрать как JSON-объект командой и работать с данными напрямую.

Последняя команда отправляет в ответ то, что написано в двойных кавычках. Там мы обращаемся к переменной $data, где хранятся присланные данные. Именно этот ответ будет обрабатывать скрипт на JavaScript, в функции xhr.onreadystatechange, которую мы прописали раньше.

Сам код нам нужно сохранить как json.php и положить в папку /projects/json/ на нашем сайте — так мы прописали в скрипте на JavaScript.

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

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

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

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

Проксирование

Самый простой способ обойти это ограничение — проксирование. Допустим, мы хотим сделать запрос с http://site.com на http://remote.com/get.html.

Чтобы обойти ограничение, вместо указания remote.com в методе open(), там ставится специальный URL вида http://site.com/proxy/remote.com/get.html. Так что запрос приходит на наш веб-сервер, который проксирует его на сервер site.com, который в свою очередь обрабатывает этот запрос, как нужно.

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

Проксирование настраивается соответствующим модулем (mod_proxy, proxy module и т.п.) веб-сервера для всех адресов, начинающихся на /proxy.

Например, при использовании web-сервера Apache, для проксирования нужны директивы ProxyPass, ProxyPassReverse. Кроме того, доступны еще модули, которые по необходимости правят урлы, разархивируют контент

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

Часто кроссбраузерные запросы — это

  1. Способ обойти ограничения в 2 одновременных соединения к одному домену-порту.
  2. Способ использовать два разных сервера в общении с посетителем. Например, на chat.site.ru — чат-демон, на www.site.ru — веб-сервер.

Кросс-доменные запросы с поддомена типа http://a.site.com, http://b.site.com на базовый домен site.com допустимы при использовании свойства document.domain, которое надо установить в site.com

// на странице a.site.com
...
document.domain='site.com'
...
// все, теперь могу делать XmlHttpRequest на site.com
xmlhttp.open(..'http://site.com/feedme.php'..)

Запрос на старый домен

В браузере Internet Explorer, чтобы сделать запрос на старый домен a.site.com, нужно вернуть свойство document.domain обратно. В остальных браузерах это приводит к ошибке, поэтому можно оформить код типа такого:

var oldDomain = document.domain
document.domain = "site.com"
try {
    // для IE, в остальных браузерах ошибка...
    document.domain = oldDomain;
} catch(e) {  /* ... но в них все и так работает */ }
//... работаем с a.site.com ...

Same origin и фреймы

Приятным бонусом свойства document.domain является возможность коммуникации между фреймами/ифреймами на одном домене.

То есть, например, если

  • во фрейме с адреса http://a.site.com установлен document.domain=’site.com’,
  • на фрейме с адреса http://b.site.com установлен домен document.domain=’site.com’
  • на фрейме с адреса http://site.com установлен (обязательно!) домен document.domain=’site.com’

То эти три фрейма могут свободно общаться посредством javascript и XmlHttpRequest.

Обычно такая коммуникация используется при создании чатов/событий с сервера, когда на site.com находится основной веб-сервер, а на chat.site.com висит чат-демон.

Internet Explorer trusted zone

Любые запросы допустимы между сайтами, находящимися в доверенной (trusted) зоне Internet Explorer. Так что, внутренний корпоративный портал может быть у всех пользователей в этой зоне, и он сможет делать запросы к любым сайтам.

XhrIframeProxy

Еще один хитрый подход называется , и позволяет делать XmlHttpRequest к любым доменам при помощи хитрого iframe-хака. Он основан на том, что фреймы с разных доменов могут читать и менять друг у друга anchor, т.е часть адреса после решетки ‘#’. За счет этого организуется специальный протокол, по которому «проксируется» XmlHttpRequest.

Этот метод, в принципе, вполне жизнеспособен, особенно для небольшого объема данных.

Кросс-доменные запросы в FF3/IE8/Opera9..

В спецификации HTML 5 предусмотрены кросс-доменные запросы .

Создатели Firefox и Opera реализовали этот вариант, см. например MDC: .

Разработчики IE8 пошли другим путем и предлагают .

Оба способа вполне жизнеспособны и уже пригодны для использования в интранет-приложениях, когда на всех машинах администратор ставит одинаковый браузер, например, Firefox 3 ?

Извлечение данных

Загрузка файла в виде двоичного объекта с помощью XHR всегда была проблемой. С технической точки зрения это было даже невозможно. Один из известных способов заключается в переопределении mime-типа пользовательской кодировкой, как показано ниже.

Ранее содержимое картинки можно было извлечь таким способом:

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);

// Hack to pass bytes through unprocessed.
xhr.overrideMimeType('text/plain; charset=utf-8');

xhr.onreadystatechange = function(e) {
  if (this.readyState == 4 && this.status == 200) {
    var binStr = this.responseText;
    for (var i = 0, len = binStr.length; i < len; ++i) {
      var c = binStr.charCodeAt(i);
      //String.fromCharCode(c & 0xff);
      var byte = c & 0xff;  // byte at offset i
    }
  }
};

xhr.send();

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

Указание формата ответа

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

xhr.responseType

Прежде чем отправить запрос, необходимо задать для свойства значение text, arraybuffer, blob или document

Обратите внимание: если установить значение или опустить его, по умолчанию выбирается формат text.
xhr.response

После успешного выполнения запроса свойство response будет содержать запрошенные данные в формате , , или в соответствии со значением .. Переработаем предыдущий пример с использованием этой новой возможности

Теперь мы извлекаем данные картинки в формате вместо строки. Передаем буфер в API и получаем объект

Переработаем предыдущий пример с использованием этой новой возможности. Теперь мы извлекаем данные картинки в формате вместо строки. Передаем буфер в API и получаем объект .

BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
  if (this.status == 200) {
    var bb = new BlobBuilder();
    bb.append(this.response); // Note: not xhr.responseText

    var blob = bb.getBlob('image/png');
    ...
  }
};

xhr.send();

Так намного лучше.

Ответы в формате ArrayBuffer

 – это стандартный контейнер фиксированной длины для двоичных данных. Это очень удобный универсальный буфер для необработанной информации, но его главное достоинство – возможность создавать «представления» исходных данных с помощью типизированных массивов JavaScript. Фактически на базе одного источника можно сформировать несколько представлений. Например, можно создать 8-битный целочисленный массив, который использует тот же объект , что и 32-битный массив на базе тех же данных. Исходная информация остается неизменной: она просто представляется в разном виде.

В примере ниже мы извлекаем ту же картинку в формате , но на этот раз создаем из данных в буфере 8-битный целочисленный массив.

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
  var uInt8Array = new Uint8Array(this.response); // this.response == uInt8Array.buffer
  // var byte3 = uInt8Array; // byte at offset 4
  ...
};

xhr.send();

Ответы в формате Blob

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

window.URL = window.URL || window.webkitURL;  // Take care of vendor prefixes.

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
  if (this.status == 200) {
    var blob = this.response;

    var img = document.createElement('img');
    img.onload = function(e) {
      window.URL.revokeObjectURL(img.src); // Clean up after yourself.
    };
    img.src = window.URL.createObjectURL(blob);
    document.body.appendChild(img);
    ...
  }
};

xhr.send();

Объект можно использовать по разному: например, сохранить его в индексированной базе данных, записать в файловую систему HTML5 или , как показано в этом примере.

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

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

Вначале рассмотрим общее кодирование запросов, ниже — правильную работу с русским языком для windows-1251.

Существуют два вида кодирования HTTP-запроса. Основной — urlencoded, он же — стандартное кодирование URL. Пробел представляется как %20, русские буквы и большинство спецсимволов кодируются, английские буквы и дефис оставляются как есть.

Способ, которым следует кодировать данные формы при submit’е, задается в ее HTML-таге:

<form method="get"> // метод GET с кодировкой по умолчанию
<form method="post" enctype="application/x-www-form-urlencoded"> // enctype явно задает кодировку
<form method="post"> // метод POST с кодировкой по умолчанию (urlencoded, как и предыдущая форма)

Если форма submit’ится обычным образом, то браузер сам кодирует (urlencode) название и значение каждого поля данных ( и т.п.) и отсылает форму на сервер в закодированном виде.

Формируя XmlHttpRequest, мы должны формировать запрос «руками», кодируя поля функцией .

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

Например, для посылки GET-запроса с произвольными параметрами name и surname, их необходимо закодировать вот так:

// Пример с GET
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("GET", '/script.html?'+params, true)
...
xmlhttp.send(null)

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

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

// Пример с POST
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("POST", '/script.html', true)
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
...
xmlhttp.send(params)

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

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

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

<form method="post" enctype="multipart/form-data">

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

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

Кодировка (языковая)

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

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

<?php
// ajax.php
$name = iconv('UTF8','CP1251',$_GET);
?>

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

<?php
// ajax.php
header('Content-Type: text/plain; charset=utf-8');
?>

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

# в конфиге апача
AddDefaultCharset windows-1251

Using FormData objects

The object lets you compile a set of key/value pairs to send using . It’s primarily intended for use in sending form data, but can be used independently from forms in order to transmit keyed data. The transmitted data is in the same format that the form’s  method would use to send the data if the form’s encoding type were set to «multipart/form-data».

You can build a object yourself, instantiating it then appending fields to it by calling its method, like this:

This example builds a object containing values for fields named «username» and «accountnum», then uses the method  to send the form’s data.

To construct a object that contains the data from an existing , specify that form element when creating the object:

newFormData = new FormData(someFormElement);

For example:

You can also add data to the object between retrieving it from a form and sending it, like this:

This lets you augment the form’s data before sending it along, to include additional information that’s not necessarily user editable on the form.

You can also send files using . Simply include an element of type «file»:

Then you can send it using code like the following:

Note that this example is directing the output to a Perl CGI script running on the server, and handles HTTP errors, although not prettily.

Когда событие запускается

Метод обратного вызова загрузки запускается в процессе загрузки данных. Метод обратного вызова XHR в основном запускается во время ответа на загрузку данных. Конкретное время запуска показано в следующей таблице:

событие Время срабатывания
onreadystatechange Срабатывает при изменении значения readyState, кроме случаев, когда оно изменяется с ненулевого на нулевое.
onloadstart Когда вызывается метод отправки, запускается xhr.onloadstart, а затем запускается xhr.upload.onloadstart, что означает начало загрузки данных.
onprogress Xhr.upload.onprogress будет запускаться во время загрузки данных, xhr.onprogress будет запускаться во время загрузки данных, onprogress будет запускаться каждые 50 мс
onabort Он сработает после вызова метода прерывания
onerror Он будет срабатывать при возникновении сетевого исключения. Если процесс загрузки данных не завершился, то сначала будет запущено xhr.upload.onerror, а затем xhr.onerror; если процесс загрузки данных завершился, будет только xhr срабатывает в это время .onerror
onload Успешная загрузка данных вызовет xhr.upload.onload; успешная загрузка данных вызовет xhr.onload
ontimeout Это событие будет инициировано, когда время ответа сервера превышает указанное время ожидания.
onloadend Когда загрузка данных завершена (успешная или неудачная), запускается xhr.upload.onloadend; когда загрузка данных завершена (успешная или неудачная), запускается xhr.onloadend

See also

  • MDN articles about XMLHttpRequest:
    • AJAX — Getting Started
    • Using XMLHttpRequest
    • HTML in XMLHttpRequest
  • XMLHttpRequest references from W3C and browser vendors:
    • W3C: XMLHttpRequest (base features)
    • W3C: XMLHttpRequest (latest editor’s draft with extensions to the base functionality, formerly XMLHttpRequest Level 2
    • Microsoft documentation
  • «Using the XMLHttpRequest Object» (jibbering.com)
  • XMLHttpRequest — REST and the Rich User Experience
  • HTML5 Rocks — New Tricks in XMLHttpRequest2
  • Thread on the naming convention of
  • — how to access from JSM modules etc which do not have access to DOM

    • Components.utils.importGlobalProperties
    • nsIXMLHttpRequest

Асинхронный = False

Чтобы использовать асинхр = ложь, измените третий параметр в open() метода к ложным:

xmlhttp.open(«GET», «xmlhttp_info.txt», false);

Использование асинхр = False не рекомендуется, но в течение нескольких небольших запросов это может быть в порядке.

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

Note: При использовании асинхронной = ложь, не пишите функцию onreadystatechange — просто поместите код после send() заявление:

пример

xmlhttp.open(«GET», «xmlhttp_info.txt», false);
xmlhttp.send();
document.getElementById(«demo»).innerHTML = xmlhttp.responseText;

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

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

Синхронный XMLHttpRequest

В этом примере через XMLHTTPRequest с сервера запрашивается страница http://example.org/, и текст ответа сервера показывается через alert().

var xmlhttp = getXmlHttp()
xmlhttp.open('GET', '/xhr/test.html', false);
xmlhttp.send(null);
if(xmlhttp.status == 200) {
  alert(xmlhttp.responseText);
}

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

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

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

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

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

var xmlhttp = getXmlHttp()
xmlhttp.open('GET', '/xhr/test.html', true);
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4) {
     if(xmlhttp.status == 200) {
       alert(xmlhttp.responseText);
         }
  }
};
xmlhttp.send(null);

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

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

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

  • 0 — Unitialized
  • 1 —
  • 2 — Loaded
  • 3 — Interactive
  • 4 — Complete

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

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

Firefox дает такой доступ, но для обработки запроса по частям состояние Interactive все равно неудобно из-за сложностей обнаружения ошибок соединения.
Поэтому Interactive тоже не используется.

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

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

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

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

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

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

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

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

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

var xmlhttp = getXmlHttp()
xmlhttp.open("POST", "/someurl", true);
xmlhttp.onreadystatechange=function(){
  if (xmlhttp.readyState != 4) return
  clearTimeout(timeout) // очистить таймаут при наступлении readyState 4
  if (xmlhttp.status == 200) {
      // Все ок
      ...
      alert(xmlhttp.responseText);
      ...
  } else {
      handleError(xmlhttp.statusText) // вызвать обработчик ошибки с текстом ответа
  }
}
xmlhttp.send("a=5&b=4");
// Таймаут 10 секунд
var timeout = setTimeout( function(){ xmlhttp.abort(); handleError("Time over") }, 10000);
function handleError(message) {
  // обработчик ошибки
  ...
  alert("Ошибка: "+message)
  ...
}

Готовим HTML-страницу

У нас будет очень простая страница, потому что самое важное сейчас — научиться работать с JSON-форматом, а красоту наведём позже. На странице нам понадобятся:

На странице нам понадобятся:

  • заголовок;
  • два поля ввода, чтобы вы могли ввести туда любые данные и убедиться, что отправка работает;
  • кнопка, которая отправляет JSON на сервер;
  • место для вывода результата — там мы выведем то, что пришлёт нам сервер в ответ.

Мы сразу подключим jQuery, чтобы в скрипте напрямую обращаться к полям ввода и месту для вывода результата. А ещё заранее зададим синий цвет для вывода ответа от сервера — так мы сразу отличим данные на странице от того, что нам ответил сервер.

На языке HTML это будет так:

Внешний вид очень простой, чтобы проверить работоспособность всей системы

Other signatures


  • a simple string instead of the options. In this case, a GET request will be made to that url.


  • the above may also be called with the standard set of options.

The module has convience functions attached that will make requests with the given method.
Each function is named after its method, with the exception of which is called for compatibility.

The method shorthands may be combined with the url-first form of for succinct and descriptive requests. For example,

xhr.post('/post-to-me',function(err,resp){console.log(resp.body)})

or

xhr.del('/delete-me',{ headers{ my'auth'}},function(err,resp){console.log(resp.statusCode);})

История XMLHttpRequest

Концепция Javascript XMLHttpRequest создавалась специалистами Outlook Web Access для применения на сервере Microsoft Exchange 2000. Версии 5 и 6 не определяли идентификатор объекта XHR на своих языках сценариев, поскольку сам идентификатор Request не был стандартным на момент выпуска. Microsoft добавила идентификатор объекта на свои языки сценариев в Internet Explorer 7.0, выпущенный в октябре 2006 года. В проекте браузера был разработан и реализован интерфейс Javascript XMLHttpRequest в механизм компоновки Gecko.

Он был смоделирован таким образом, чтобы максимально быть похожим на интерфейс Microsoft Request. Mozilla создал оболочку для использования этого интерфейса через объект JS, который был назван XMLHttpRequest. Объект уже сделали доступным в Gecko версии 0.6, выпущенной 6 декабря 2000 года, но он еще не был полностью функциональным до тех пор, пока 5 июня 2002 года не вышла версия 1.0 Gecko, после чего идентификатор объекта стал стандартом де-факто в других крупных веб-системах:

  • Safari 1.2, выпущенном в феврале 2004 года.
  • Opera 8.0, выпущенном в апреле 2005 года.
  • iCab 3.0b352, выпущенном в сентябре 2005 года.

С появлением кросс-браузерных библиотек JavaScript, таких как jQuery, разработчики могут вызывать функциональность Javascript XMLHttpRequest без кодирования непосредственно в API. Wide Web Consortium World опубликовал проект спецификации для XMLHttpRequest 5 апреля 2006 года с целью документации минимального набора совместимых функций на основе существующих реализаций, позволяя разработчикам использовать их без кода, специфичного для платформы.

25 февраля 2008 года W3C также опубликовал еще одну спецификацию рабочего проекта — XMLHttpRequest Level 2. Уровень 2 состоит из расширенной функциональности, включая поддержку для запросов и обработку байтовых потоков.

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

open()

Варианты вызова:

  • open( method, URL )
  • open( method, URL, async )
  • open( method, URL, async, userName )
  • open( method, URL, async, userName, password )

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

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

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

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

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

send()

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

abort()

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

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

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

setRequestHeader(name, value)

Устанавливает заголовок name запроса со значением value. Если заголовок с таким name уже есть — он заменяется.

Например,

xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Example Explained

1: Create an array of objects.

Use an array literal to declare an array of
objects.

Give each object two properties:
display and url.

Name the array myArray:

myArray

var myArray = [
{
«display»: «JavaScript Tutorial»,
«url»: «https://www.w3schools.com/js/default.asp»
},
{
«display»: «HTML Tutorial»,
«url»: «https://www.w3schools.com/html/default.asp»
},
{
«display»: «CSS Tutorial»,
«url»: «https://www.w3schools.com/css/default.asp»
}
]

2: Create a JavaScript function to display the array. 

Create a function myFunction() that loops the array objects,
and display the content as HTML links:

myFunction()

function myFunction(arr) {
    var out = «»;    var i;
    for(i = 0; i < arr.length; i++) {
        out += ‘<a href=»‘ + arr.url + ‘»>’ + arr.display + ‘</a><br>’;
    }
    document.getElementById(«id01»).innerHTML = out;
}

Call myFunction() with myArray as argument:

myFunction(myArray);

3: Create a text file

Put the array literal in a file named myTutorials.txt:

myTutorials.txt

[
{
«display»: «JavaScript Tutorial»,
«url»: «https://www.w3schools.com/js/default.asp»
},
{
«display»: «HTML Tutorial»,
«url»: «https://www.w3schools.com/html/default.asp»
},
{
«display»: «CSS Tutorial»,
«url»: «https://www.w3schools.com/css/default.asp»
}
]

4: Read the text file with an XMLHttpRequest

Write an XMLHttpRequest to read the text file, and use
myFunction() to display the
array:

XMLHttpRequest

var xmlhttp = new XMLHttpRequest();var url = «myTutorials.txt»;
xmlhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {    var myArr = JSON.parse(this.responseText);   
myFunction(myArr);    }};xmlhttp.open(«GET»,
url, true);xmlhttp.send();

❮ Previous
Next ❯

The onreadystatechange Property

The property holds the status of the XMLHttpRequest.

The property defines a callback function to be executed when the readyState changes.

The property and the property holds the status of the XMLHttpRequest object.

Property Description
onreadystatechange Defines a function to be called when the readyState property changes
readyState Holds the status of the XMLHttpRequest.
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
status 200: «OK»403: «Forbidden»
404: «Page not found»For a complete list go to the
Http Messages Reference
statusText Returns the status-text (e.g. «OK» or «Not Found»)

The function is called every time the readyState changes.

When is 4 and status is 200, the response is ready:

Example

function loadDoc() {
  const 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»);
  xhttp.send();
}

The event is triggered four times (1-4), one time for each change in the readyState.

❮ Previous
Next ❯

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

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

Adblock
detector