Xmlhttprequest

Основы

XMLHttpRequest имеет два режима работы: синхронный и асинхронный.

Сначала рассмотрим асинхронный, так как в большинстве случаев используется именно он.

Чтобы сделать запрос, нам нужно выполнить три шага:

  1. Создать .

  2. Инициализировать его.

    Этот метод обычно вызывается сразу после . В него передаются основные параметры запроса:

    • – HTTP-метод. Обычно это или .
    • – URL, куда отправляется запрос: строка, может быть и объект URL.
    • – если указать , тогда запрос будет выполнен синхронно, это мы рассмотрим чуть позже.
    • , – логин и пароль для базовой HTTP-авторизации (если требуется).

    Заметим, что вызов , вопреки своему названию, не открывает соединение. Он лишь конфигурирует запрос, но непосредственно отсылается запрос только лишь после вызова .

  3. Послать запрос.

    Этот метод устанавливает соединение и отсылает запрос к серверу. Необязательный параметр содержит тело запроса.

    Некоторые типы запросов, такие как , не имеют тела. А некоторые, как, например, , используют , чтобы отправлять данные на сервер. Мы позже увидим примеры.

  4. Слушать события на , чтобы получить ответ.

    Три наиболее используемых события:

    • – происходит, когда получен какой-либо ответ, включая ответы с HTTP-ошибкой, например 404.
    • – когда запрос не может быть выполнен, например, нет соединения или невалидный URL.
    • – происходит периодически во время загрузки ответа, сообщает о прогрессе.

Вот полный пример. Код ниже загружает с сервера и сообщает о прогрессе:

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

Код состояния HTTP (число): , , и так далее, может быть в случае, если ошибка не связана с HTTP.
Сообщение о состоянии ответа HTTP (строка): обычно для , для , для , и так далее.
(в старом коде может встречаться как )
Тело ответа сервера.

Мы можем также указать таймаут – промежуток времени, который мы готовы ждать ответ:

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

URL с параметрами

Чтобы добавить к URL параметры, вида , и корректно закодировать их, можно использовать объект URL:

Стандарты

World Wide Web Consortium опубликовал Рабочий проект спецификации для XMLHttpRequest объекта 5 апреля 2006 года, отредактированный на Энн ван Кестерен из Opera Software и Дин Джексон из W3C. Его цель — «задокументировать минимальный набор функционально совместимых функций на основе существующих реализаций, позволяющий веб-разработчикам использовать эти функции без кода, специфичного для платформы».

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

В конце 2012 года WHATWG взялась за разработку и поддержание уровня жизни с помощью Web IDL . Текущие проекты W3C основаны на снимках стандарта WHATWG .

§Real-Time Notifications and Delivery

XHR enables a simple and efficient way to synchronize client updates
with the server: whenever necessary, an XHR request is dispatched by the
client to update the appropriate data on the server. However, the same
problem, but in reverse, is much harder. If data is updated on the
server, how does the server notify the client?

HTTP does not provide any way for the server to initiate a new
connection to the client. As a result, to receive real-time
notifications, the client must either poll the server for updates or
leverage a streaming transport to allow the server to push new
notifications as they become available. Unfortunately, as we saw in the
preceding section, support for XHR streaming is limited, which leaves us
with XHR polling.

«Real-time» has different meanings for different applications: some
applications demand submillisecond overhead, while others may be just
fine with delays measured in minutes. To determine the optimal
transport, first define clear latency and overhead targets for your
application!

Отправляем данные на сервер

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

К сча­стью, инже­не­ры дав­но при­ду­ма­ли, как отправ­лять дан­ные на сер­вер, не пере­за­гру­жая стра­ни­цу. Для это­го исполь­зу­ют JavaScript.

Что­бы отпра­вить запрос, нам пона­до­бит­ся встро­ен­ный объ­ект XMLHttpRequest(). Вот как мы вво­дим его в повествование:

// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();

Для запро­са нам нуж­но знать адрес, куда будем отправ­лять наш JSON — это и есть адрес наше­го скрип­та, кото­рый мы напи­шем поз­же. Мы будем писать его на PHP, поэто­му зара­нее можем при­ду­мать ему имя и адрес, где он будет лежать: http://mihailmaximov.ru/projects/json/json.php.

// адрес, куда мы отправим нашу JSON-строку
url = «http://mihailmaximov.ru/projects/json/json.php»;

Когда мы зна­ем адрес, мы можем открыть соеди­не­ние, что­бы сер­вер был готов при­нять наши дан­ные. Это зна­чит, что мы пока ниче­го цен­но­го туда не посы­ла­ем, а про­сто пре­ду­пре­жда­ем сер­вер, что ско­ро что-то прилетит:

// открываем соединение. url — это переменная с нашим адресом
xhr.open(«POST», url, true);

Теперь напи­шем заго­ло­вок запро­са, что­бы сер­вер пони­мал, какие дан­ные мы ему при­шлём и как ему их обра­ба­ты­вать. Так как у нас JSON, то это и про­пи­шем в заголовке:

 // устанавливаем заголовок — выбираем тип контента, который отправится на сервер, в нашем случае мы явно пишем, что это JSON
setRequestHeader(«Content-Type», «application/json»);

Чуть ниже сра­зу про­пи­шем пове­де­ние скрип­та на слу­чай отве­та сер­ве­ра. Сер­вер дол­жен обра­бо­тать наши дан­ные, вер­нуть ответ, а мы долж­ны этот ответ пой­мать и выве­сти на страницу:

Послед­нее, что нам оста­лось сде­лать, — выта­щить наши вве­дён­ные дан­ные из полей, собрать из них JSON и отпра­вить на сервер:

 // преобразуем наши данные JSON в строку
      var data = JSON.stringify({ «name»: name.value, «lastname»: lastname.value });
      // когда всё готово, отправляем JSON на сервер
      xhr.send(data);
Готовый скрипт на странице

Отправка данных

Возможность очень важна, но она совершенно бесполезна, если эти данные нельзя отправить обратно (на сервер). До недавнего времени в можно было отправлять только данные или (XML). Ситуация изменилась. Переработанный метод позволяет отправлять данные любых типов: , , , , и . Примеры в этой части раздела иллюстрируют отправку данных каждого из этих типов.

Отправка строковых данных: xhr.send(DOMString)

function sendText(txt) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) {
    if (this.status == 200) {
      console.log(this.responseText);
    }
  };

  xhr.send(txt);
}

sendText('test string');
function sendTextNew(txt) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.responseType = 'text';
  xhr.onload = function(e) {
    if (this.status == 200) {
      console.log(this.response);
    }
  };
  xhr.send(txt);
}

sendText2('test string');

Как видите, ничего нового. Хотя правая часть несколько отличается. В ней есть строка . Впрочем, ее отсутствие не меняет результат.

Отправка данных форм: xhr.send(FormData)

Многие из нас привыкли пользоваться плагинами jQuery и другими библиотеками для отправки форм AJAX. Вместо них можно использовать  – еще один новый тип данных в рамках технологии XHR2. Тип очень удобен для динамического создания HTML-элементов с помощью JavaScript. Затем эти формы можно отправить с помощью AJAX.

function sendForm() {
  var formData = new FormData();
  formData.append('username', 'johndoe');
  formData.append('id', 123456);

  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);
}

По сути, мы просто динамически создаем элемент и добавляем в нее поля с помощью метода append.

При этом можно не создавать с нуля. Объекты можно инициализировать с помощью существующих на странице элементов . Например:

<form id="myform" name="myform" action="/server">
  <input type="text" name="username" value="johndoe">
  <input type="number" name="id" value="123456">
  <input type="submit" onclick="return sendForm(this.form);">
</form>
function sendForm(form) {
  var formData = new FormData(form);

  formData.append('secret_token', '1234567890'); // Append extra data before send.

  var xhr = new XMLHttpRequest();
  xhr.open('POST', form.action, true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);

  return false; // Prevent page from submitting.
}

HTML-форма может содержать файлы (например, ). Объект тоже поддерживает эту возможность. Достаточно просто прикрепить файлы, и браузер выполнит запрос при вызове метода .

function uploadFiles(url, files) {
  var formData = new FormData();

  for (var i = 0, file; file = files; ++i) {
    formData.append(file.name, file);
  }

  var xhr = new XMLHttpRequest();
  xhr.open('POST', url, true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);  // multipart/form-data
}

document.querySelector('input').addEventListener('change', function(e) {
  uploadFiles('/server', this.files);
}, false);

Отправка файла или объекта Blob: xhr.send(Blob)

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

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

<progress min="0" max="100" value="0">0% complete</progress>
function upload(blobOrFile) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) { ... };

  // Listen to the upload progress.
  var progressBar = document.querySelector('progress');
  xhr.upload.onprogress = function(e) {
    if (e.lengthComputable) {
      progressBar.value = (e.loaded / e.total) * 100;
      progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
    }
  };

  xhr.send(blobOrFile);
}

// Take care of vendor prefixes.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;

var bb = new BlobBuilder();
bb.append('hello world');

upload(bb.getBlob('text/plain'));

Отправка произвольного набора байтов: xhr.send(ArrayBuffer)

В качестве полезных данных XHR также можно отправлять объекты .

function sendArrayBuffer() {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) { ... };

  var uInt8Array = new Uint8Array();

  xhr.send(uInt8Array.buffer);
}

Основы AJAX

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

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

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

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

Использование 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)
  ...
}

«Непростые» запросы

В кросс-доменном можно указать не только , но и любой другой метод, например , .

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

Чтобы пресечь любые недопонимания, браузер использует предзапрос в случаях, когда:

  • Если метод – не GET / POST / HEAD.
  • Если заголовок имеет значение отличное от , или , например .
  • Если устанавливаются другие HTTP-заголовки, кроме , , .

…Любое из условий выше ведёт к тому, что браузер сделает два HTTP-запроса.

Первый запрос называется «предзапрос» (английский термин «preflight»). Браузер делает его целиком по своей инициативе, из JavaScript мы о нём ничего не знаем, хотя можем увидеть в инструментах разработчика.

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

Его задача – спросить сервер, разрешает ли он использовать выбранный метод и заголовки.

На этот запрос сервер должен ответить статусом 200, без тела ответа, указав заголовки и, при необходимости, .

Дополнительно он может указать , где – количество секунд, на которые нужно закэшировать разрешение. Тогда при последующих вызовах метода браузер уже не будет делать предзапрос.

Давайте рассмотрим предзапрос на конкретном примере.

Рассмотрим запрос , который используется в протоколе WebDAV для управления файлами через HTTP:

Этот запрос «непростой» по двум причинам (достаточно было бы одной из них):

  1. Метод .
  2. Заголовок .

Поэтому браузер, по своей инициативе, шлёт предварительный запрос :

Обратим внимание на детали:

  • Адрес – тот же, что и у основного запроса: .
  • Стандартные заголовки запроса , , присутствуют.
  • Кросс-доменные специальные заголовки запроса:
    • – домен, с которого сделан запрос.
    • – желаемый метод.
    • – желаемый «непростой» заголовок.

На этот запрос сервер должен ответить статусом 200, указав заголовки и .

Но в протоколе WebDav разрешены многие методы и заголовки, которые имеет смысл сразу перечислить в ответе:

Ответ должен быть без тела, то есть только заголовки.

Браузер видит, что метод – в числе разрешённых и заголовок – тоже, и дальше он шлёт уже основной запрос.

При этом ответ на предзапрос он закэширует на 86400 сек (сутки), так что последующие аналогичные вызовы сразу отправят основной запрос, без .

Основной запрос браузер выполняет уже в «обычном» кросс-доменном режиме:

Ответ сервера, согласно спецификации , может быть примерно таким:

Так как содержит правильный домен, то браузер вызовет и запрос будет завершён.

HTTP-headers

allows both to send custom headers and read headers from the response.

There are 3 methods for HTTP-headers:

Sets the request header with the given and .

For instance:

Headers limitations

Several headers are managed exclusively by the browser, e.g. and .
The full list is .

is not allowed to change them, for the sake of user safety and correctness of the request.

Can’t remove a header

Another peculiarity of is that one can’t undo .

Once the header is set, it’s set. Additional calls add information to the header, don’t overwrite it.

For instance:

Gets the response header with the given (except and ).

For instance:

Returns all response headers, except and .

Headers are returned as a single line, e.g.:

The line break between headers is always (doesn’t depend on OS), so we can easily split it into individual headers. The separator between the name and the value is always a colon followed by a space . That’s fixed in the specification.

So, if we want to get an object with name/value pairs, we need to throw in a bit JS.

Like this (assuming that if two headers have the same name, then the latter one overwrites the former one):

Async = false

To use async = false, change the third parameter in the open() method to false:

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

Using async = false is not recommended, but for a few small requests this can be ok.

Remember that the JavaScript will NOT continue to execute,
until the server response is ready. If the server is busy or slow, the
application will hang or stop.

Note: When you use async = false, do NOT write an onreadystatechange
function — just put the code after the send() statement:

Example

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

Ограничения безопасности. Кросс-доменный 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 ?

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

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

Adblock
detector