Пропустить навигацию.
Главная

XMLHTTPRequest: описание, применение, частые проблемы

Здесь Вы найдете полное описание объекта XMLHTTPRequest, способы использования, форматы данных и разбор частых проблем. На отдельной страничке - спецификация объекта XMLHTTPRequest, согласно W3C.

Полезного чтения.


Объект XMLHttpRequest

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

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

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

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

function getXmlHttp(){
  var xmlhttp;
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}
Функция тупо перебирает возможные внутренние реализации и возвращает начальный объект XMLHttpRequest. Существует и масса других рабочих кроссбраузерных функций, однако все они по сути делают то же самое.

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

Здесь сначала создается запрос, задается открытие (open) синхронного соединение с адресом /xhr/test.html и запрос отсылается с null, т.е без данных: send(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 - Loading
  • 2 - Loaded
  • 3 - Interactive
  • 4 - Complete

Состояния 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 секунд.

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

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

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)
  ...
}

Методы объекта 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-запроса тела нет, поэтому используется send(null), а для 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')

getAllResponseHeaders()

Возвращает строку со всеми HTTP-заголовками ответа сервера.

getResponseHeader(headerName)

Возвращает значение заголовка ответа сервера с именем headerName.

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

onreadystatechange

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

readyState

Номер состояния запроса от 0 до 4. Используйте только 4 ("completed").

responseText

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

responseXML

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

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

var authorElem = xmlhttp.responseXML.getElementById('author')

Чтобы браузер распарсил ответ сервера в свойство 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-запросы. Кодировка.

Во время обычного 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) название и значение каждого поля данных (input и т.п.) и отсылает форму на сервер в закодированном виде.

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

Конечно, пропускать через 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, а в теле, посылаемом через send(). Поэтому params нужно указывать не в адресе, а при вызове send()

Кроме того, при 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-запрос, загружающий на сервер файл. Функционал создания таких запросов есть, в частности, во фреймворке dojo. Но можно реализовать его и самому, прочитав о нужном формате тела POST и заголовках.

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

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

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

// ajax.php
$name = iconv('UTF8','CP1251',$_GET['name']);

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

// ajax.php
header('Content-Type: text/plain; charset=windows-1251');
Или же, такой заголовок должен добавить сервер. Например, в apache автоматически добавляется кодировка опцией:
# в конфиге апача
AddDefaultCharset windows-1251

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

Кеширование

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

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

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

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

xmlhttp.open("GET", "/service.php?r="+Math.random(), true)

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

Пример демонстрирует универсальный код работы с кешем для Internet Explorer и Firefox. Этот пример обеспечивает посылку "If-Modified-Sinse"-заголовка IE при обращениях к закешированному запросу.

var xmlhttp = getXmlHttp()
xmlhttp.open("GET", uri, false); // синхронный запрос для примера
xmlhttp.send(null);
if(!xmlhttp.getResponseHeader("Date")) {  // 1
  var cached = xmlhttp;
  xmlhttp = getXmlHttp()
  var ifModifiedSince = cached.getResponseHeader("Last-Modified");
  ifModifiedSince = (ifModifiedSince) ? ifModifiedSince : new Date(0); // January 1, 1970
  xmlhttp.open("GET", uri, false);
  xmlhttp.setRequestHeader("If-Modified-Since", ifModifiedSince);
  xmlhttp.send(null);
  if(xmlhttp.status == 304)  {
    xmlhttp = cached;
  }
}

Разбор примера работы с кешем

Внешний тест (1) опирается на то, что в 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 не нужно, даже если текущий запрос еще не завершился.

Повторный XmlHttp-запрос после abort() зависает

С этой проблемой я сталкивался только в IE под Windows. Ее причины - в том, что abort() не обрывает TCP-соединение, а оставляет его висеть до наступления таймаута (см. метод abort()). Если же к домену есть два TCP-соединения (даже ждущие таймаута), то третье будет висеть, пока какое-то из них не помрет.

XmlHttpRequest виснет в IE7 (много табов)

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

Она связана с ограничением в 2 одновременных соединения к одному домену. Точнее, с тем фактом, что это ограничение в IE7 действует не на один таб, а на все. Так что, если есть два таба с непрерывным соединением, то при открытии третьего таба - XmlHttpRequest с него к тому же домену просто зависнет и будет ждать окончания одного из двух предыдущих запросов.

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

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

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

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

Firefox ставит responseXML вида <parseerror>...</parseerror>

Да, у браузеров типа Mozilla это такой способ сказать, что документ невалидный.

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

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

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

Это создает проблему, если хочется взять контент с другого сайта. Как правило, в этом случае вместо XmlHttpRequest используются другие средства, например, загрузка через динамически создаваемый тег <script>. Но, конечно, 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"

... работаем с 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

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

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

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

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

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

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

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

Поддержка в библиотеках и фреймворках

Практически каждая javascript-библиотека или javascript-фреймворк включает в том или ином виде поддержку XmlHttpRequest-запросов и других способов прозрачного общения с сервером. Берите фреймворк по другим параметрам, а какая-то поддержка так обязательно будет.

Javascript-библиотеки

Dojo toolkit

Наиболее профессионально общение с сервером, на мой взгляд, сделано в dojo. Для удобства работы с асинхронными вызовами, в dojo и Mochikit используется специальный объект Deferred. Умеет посылать формы, отменять запросы, позволяет строить сложные цепочки асинхронных вызовов. В dojo для этого используется вызов dojo.xhrGet, который позволяет указывать обработчик, таймаут и формат запроса (например, JSON). Также умеет предотвращать кеширование (preventCache), передавать объекты/формы с файлами.

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

Yahoo UI (YUI)

В Yahoo UI соединениями с сервером заведует Connection Manager. Главная фунция asyncRequest принимает в качестве одного из параметров (callback) объект, который позволяет подписываться на события, указывать timeout и посылать на сервер объект. Кроме того можно указывать временной промежуток для автоматических опросов. Например, опрашивать новости с сервера каждые 3 секунды. Метод setForm передает форму, умеет загружать файлы.

Prototype

Во фреймворке prototype Ajax представлен рядом классов вида Ajax.*. В сочетании с другими методами библиотеки - предоставляет весь стандартный функционал. Кроме того - приятный бонус: Ajax.PeriodicalUpdater умеет легко обновлять HTML-элемент с сервера и гибко увеличивать промежуток между опросами при проблемах серверной части.

JsHttpRequest

Есть еще библиотека JsHttpRequest, которая набрала популярность за счет русской документации и коммунити. Весь базовый функционал у нее есть. Лично я ни разу не пользовался, но говорят - работает. Если Вы не знаете английского языка и не нуждаетесь в интеграции AJAX с более общим javascript-фреймворком - возможно, эта библиотека подойдет.

Серверные библиотеки

Есть специальные серверные библиотеки, которые упрощают работу с XmlHttpRequest, организуя не только javascript-часть, но и серверную тоже. Они обычно умеют, например, отображать серверные функции на php в javascript-аналоги. При вызове такого javascript-аналога библиотека сама сделает запрос на сервер, обработает его на сервере, вызовет серверную функцию и вернет ее результат.

Для PHP одной из лучших библиотек является XAJAX, для Java - DWR.

...А если...

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

Очень хорошо спасибо вам за сайт

Спасибо большое, давно искал. Теперь много стало ясно ) С наступающими)

Большое спасибо....
Как ни странн,о разбирал по косточкам Extjs_dot_com... а знания не хватило... спасибо еще раз за понятный материал и с наступившим Новым годом!

Супер. Отличный материал. Респект ;)
Возможно, к Javascript-библиотекам стоит добавить xajax.

Спасибо за столь подробно изложенный материал

Спасибо, очень многое прояснилось.

Замечательная статья, которая помогла мне разобраться с моими многодневными мытырствованиями!
Странно только что такие статьи как http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_2.html были написаны очень давно а положение вещей как я понял так и не изменилось, несмотря на работу коммитета стандартизации! везде разногласия! и еще я не понял почему нельзя обратиться к responseText в IE вне обработчика события... всмысле в тот момент, пока он ждет закрытия соединения с сервером, с помощью setTimeout(function(){alert(xhr.responseText)}, 500) - к примеру

Неплохой материал, за ссыдку на XAJAX спасибо, не знал про эту полезную вещь!

У меня вопрос, а откуда сведения что в IE происходит утечка при xmlhttp.onreadystatechange = function() { ... } , есть ли какие-нибуть тесты, чтобы можно было это увидеть своими глазами?

К вопросу о фреймворках, рекомендую jQuery
Полно доки (правда только онлайн), куча сделанных на нем всяких побрякушек.
Прост в использовании, позволяет не задумываться над кроссброузярностью и дает шикарный контроль над DOM.
Мало того, что сам маленький (~30кб), но написанный на нем код весьма компактный.
ИМХО - если и использовать фрэймворк, то этот. За него говорит тот факт, что используется Гуглом.

Спасибо большое, давно искал. Теперь много стало ясно ) С наступающими)

Спасибо огромное! Клиенты всё больше требуют web морд, а куда без javascript? Три дня искал информацию. Набрёл на http://javascript.ru/ и http://xmlhttprequest.ru/ и счастье настало!

Спасибо, все сразу стало очень понятно

Все хорошо и понятно описано, однако у меня есть замечание:
функция iconv() в php имеет другой формат - $name = iconv('UTF8','CP1251',$_GET['name']);

Ага, буквально на днях эта опечатка появилась. Исправил.

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

Здесь публикуются комментарии конкретно по статье. Все вопросы - просьба задавать на форуме, он для того и существует :)

Супер!
Очень помогло.
Гранд мерси.

Великолепно! побольше бы таких статей, интересно, а объекти ActiveXObject("Msxml2.XMLHTTP") и ActiveXObject("Microsoft.XMLHTTP") обладают теми же методами и свойствами, может кто знает?

в примере с iconv неправильно написано название кодировки - "UTF8", должно быть "UTF-8".

Правильно написано. Можно и UTF8 и UTF-8. Проверьте - убедитесь ;)

Msxml2.XMLHTTP и Microsoft.XMLHTTP обладают одинаковыми методами и свойствами, хотя и принадлежат разным версиям библиотеки MSXML.

Очень помогло, спасибо

Огромное человеческое спсибо! Только что пофиксил баг, оказалось косяк с кодировкой.

Очень полезно, спасибо!

Да уж, если бы все так подробно всё обьясняли :) Респект, я в программировании не сильно хорошо разбераюсь, но прочитав вроде всё понял, пойду шаманить :)

Отличная статья, спасибо!

То, что доктор прописал. Спасибо!

А почему забыли про jquery?
Очень удобная и компактная библиотека.
Там есть функции аяксовые.

Относительно недавно стал изучать(более плотно) JavaScript, и ваши ресурсы мне в этом очень помогают!
Огромное вам спасибо!

Добрый вечер. У меня возникла идея использовать набор (массив/хеш) объектов XMLHTTPRequest - чтоб посылать очередной GET-запрос, не дожидаясь ответа. Например, obj1 посылает GET, обработчик ждёт. В этот момент, obj2 посылает GET. Мои эксперименты подтвердили, что ответ приходит только на обработчик obj2. Получается, нет поддержки параллельных запросов?

Прочитал сегодня 100 страниц Аякс в действии Крэйна.

Спасибо автору, очень содержательно и понятно=))

Даа, туго с PHP на Яву переключаться. Но даже мне что-то стало понятнее. Спасибо за подробное разжевывание!

Спасибо огромное! Если бы не вы....

Спасибо огромнющее! Отличная инструкция!

Я не понял((

Большое спасибо! Весь день искала про вопросы кодировки при посылке запроса, помогло!

Нет слов - одни эмоции :) Спасибо за просто изложенную, но полезную прикладную статью.

огромное спасибо!

Добрый день. Вопрос насчет Кросс-доменного XMLHttpRequest:
как обойти ограничения, если джаваскрипт работает с закладок пользователя и обращается "как-бы" к удаленному серверу?

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

Очень интересно было бы увидеть пример кода с использованием "чистого" XHR (т.е. без притяжки iframe).

>Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8.
Хотелось бы уточнить, проверял ли автор сам это утверждение? Если да, то на каком конфиге?

Сам делал неоднократные проверки на Apache2.0.x-2.2.x с mod_php 5.x.x и даже при urlencoded, который по сути не привязан ни к одной из кодовых страниц, получаю в самом интерпретаторе строки именно в той кодировке, в какой была отправлена страница на клиент хотя даже через снифер видно, что браузер используемую charset не указывает! Где, что и как это происходит детально времени не было, но видимо таки его придется выкроить...

имеется следующий код

function doLoad(url)
{
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
request.onreadystatechange = processRequestChange;
request.open("GET", url, true);
request.send(null);
}
else
if (window.ActiveXObject)
{
request = new ActiveXObject("Microsoft.XMLHTTP");
if (request)
{
request.onreadystatechange = processRequestChange;
request.open("GET", url, true);
request.send();
}
}
}
function processRequestChange()
{
if (request.readyState == 4)
{
if (request.status == 200)
{
document.getElementById('timer').innerHTML=request.responseText;
screen();
}
}
}
doLoad('updatelot.php?r='+Math.random());

updatelot.php возвращает следующее:
;
tek_time_='".$hours.":".$minutes.":".$seconds."';
tek_cena_='$ad[tek_cena]';

поидее я должен получить доступ к переменным tek_time и tek_cena внутри тега , но доступа нет...
вопрос: если я неправильно думаю, то как мне это сделать?

Другими словами, как выполнить динамически сгенерированный javascript-код на странице?

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

РЕСПЕКТ АВТОРУ(АМ) - Статьтя супергрейт!!!!!!
страничку уже засейвил на крайняк

чтобы выполнить код
собстна нужно какое-нибудь событие или refresh

например по событию нажатию мышыны

ЖМИ СЮДА
где
superfunction - имя функции (которая в коде прописана, в которой весь код находится, которую хочешь выполнить)
(e) - переменная передающая некий параметр в функцию, например URL, если переменных в фукции должно быть больше, то пишешь их через запятую
EXAMPLE: superfunction(e,adf,myvar)

Автору: ссылочка на "Спецификация W3C" кривая (http://xmlhttprequest/w3c)

Спасибо автору

Поисковая система выдала адрес вашего сайта , зашла для ознакомления с вашими публикациями.

Довольно хорошая статья,видно что автор здорово потрудился.

Если можно не много по подробнее как выполнить динамически сгенерированный javascript-код на странице?

Специальные серверные библиотеки, которые упрощают работу с XmlHttpRequest, организуя не только javascript-часть, но и серверную тоже. Они обычно умеют, например, отображать серверные функции на php в javascript-аналоги. При вызове такого javascript-аналога библиотека сама сделает запрос на сервер

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

А где же найти информацию по отправке файлов. Я разобрался с http post форматом передачи, НО как мне получить тело файла? Binary Content, так сказать...
Я где то набрел на какую то функцию binary на javascript, но что-то непохоже чтобы она работала.

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

Так куда копать?. Спасибо

вы за что Котерова обижаете? У него очень хорошая библиотека

Отличная статья! Помогла разобраться. Спасибо!

«Если Вы используете только UTF-8 - пропустите эту секцию.
Все идущие на сервер параметры GET/POST … кодируются в UTF-8.»

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

ps: И, кстати, было справедливое замечание: а где jQuery? Замечательный фреймворк,
поудобнее Prototype будет, да и побыстрее.

ps2: А работа с ajax в JsHttpRequest всё-таки, имхо, менее удобна, чем в jQuery.

to arvitaly:

насколько мне известно, ни один браузер не предоставляет доступа к загружаемым файлам.
плясать следует от покоцанного в спецификации html4 (но возвращённого в html5)
аттрибута target.

смысл такой: создаётся невидимый iframe, в который и "загружается" форма со всем
её содержимым (включая, конечно же, и файл).

т. е., нужно что-то вроде:

содержимое формы

после отправки формы страница не перезагружается, а результат запроса будет
направлен в iframe (html-страница!). для сигнализирования того, что запрос
завёршён, нужно в эту страницу поместить js-код, который должен быть выполнен
в случае успешной загрузки (в простейшем случае можно обойтись и
alert('файлы загружены');, но ведь наверняка же с формой что-то нужно будет
сделать (как минимум, убрать) :)

Большое спасибо. Жаль что эта статья не выводится на первом месте по запросу "передача данных из JavaScript методом POST" если б хорошие люди не сказали, то и не узнал бы(

Спасибо за материал.
Скажите пожалуйста, не планируется ли добавить в статью примеров типичного использования XMLHTTPRequest?

Автор шикарен, статья отличная =) Кодировку только тут нашел, толковое и ясное объяснение! Спс =)

Предлагаем недорогое строительство домов из оцилиндрованного бревна и бруса. Только русские строительные бригады.

По jQuery есть несколько книг. Даже по свежей версии 1.3.

Объясните, почему нельзя использовать синхронный запрос. В том, что подвисает браузер, или есть другие проблемы? Я например, его использовал в одном проекте очень часто и ничего, нормально.

Отличный материал, спасибо!

Спасибо!

статья - супер, спасибо :)

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

Ответ по поводу эмуляции загрузки файла методом POST:

Вы уверены, что оно вам надо? Если да, то копать - в сторону формата POST-запроса.

Самое простое - посмотреть, как это реализовано в dojo.

Ответ вам, alekciy:

Я не вижу в комментариях вопросов, на которые нет ответа в статье. Задайте такой, если он у вас имеется! ;)

Все таки не плохо и довольно здорово!

Ссылка на спецификацию битая - потерели .ru http://xmlhttprequest/w3c

Спасибо, помогло!

У меня синхронный тест-пример работеат как асинхронный. В чем дело?
Юзаю XP-SP2 + FF-3
ЗЫ: На Мак-ОСи + Сфафри все работает как надо...

Тема изложена ярко, живо, оригинально. Только так и надо писать.

Столкнулся с проблемой, когда сервер возвращает

WWW-Authenticate: Basic realm="..."
HTTP/1.0 401 Unauthorized

Браузер ( в моем случае Safari) перехватывает обработку ответа и сам открывает окно для ввода пароля.

xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
alert("got Response: " +xmlHttp.status);
if (xmlHttp.status == 200) {
responceCallBack(xmlHttp.responseXML);
}
else if (xmlHttp.status == 401) {
//-->
alert(xmlHttp.responseText); // !!!! Управление передается только если в окне пароля сказать cansel
//-->
}
else {
//alert('Loading Error: ['+xmlHttp.status+'] ' +rxmlHttp.statusText);
}
}
};

знаю что у mozilla есть возможность с этим бороться xmlHttp.mozBackgroundRequest = true;
Подскажите как проявляется такая ситуация с другими броузерами и как с ней бороться ?

Отличный материал, спасиб о !

Автор шикарен, статья отличная =) Кодировку только тут нашла, толковое и ясное объяснение!

чтобы выполнить код
собстна нужно какое-нибудь событие или refresh

Спс

Про кроссбраузерность вообще молчу... try - catch - throw оказались бесполезными, из чего напрашивается резонный вывод: автор статьи демонстративно "заботится" о кроссбраузерности, но сам, по-видимому, не удосужился убедиться на личном опыте в работоспособности данной части кода. Каждый должен сам додумывать код под используемый им браузер, если только это не IE. Последние версии FF, Opera - в пролёте, завелось только на IE7.
По определённым обстоятельствам был вынужден тестировать и отлаживать код не в он-лайне в Интернете, а на локальном сервере. Всё - на win32. Зачем вводить в заблуждение доверчивых читателей проверкой if(!xmlhttp.getResponseHeader("Date")) при попытке оптимизации кода загрузки (из кеша, если не обновилась, и с сервера, если там обновилась), если при запросе документа с локального сервера из htdocs и проверке с помощью alert(xmlhttp.getAllResponseHeaders()) никакого поля "Date:" нет (сниффером фильтровал локальный траффик - поле "Date:", как оказалось, присутствует)?! При запросе из Интернета - поле видно как сниффером, так и getAllResponseHeaders(). Но не всем же нужно запрашивать страницы с внешних ресурсов. Так что проверку, видимо, следует переделать с поля Дата на проверку по какому-то другому полю.
Статья хоть и полезная, но зелёная, как крыжовник и мае. Дозревать её надобно.

Мысли вслух...
Хотя... в Интернете полно динамически генерируемых страниц, у которых всегда Дата свежая, в точности такая же, как в момент запроса. Поэтому, вполне возможно, что их сервера всегда (даже после первого запроса) возвращают это поле xmlhttprequest'у как свежее, в отличие от серверов, на которых страницы могут иметь определённый и приличный срок давности. Ещё раз замечу, что это касается только данного метода запроса ресурсов посредством xmlhttprequest, сниффер же всегда покажет пересылку поля Дата от сервера клиенту, даже если страница на сервере давно не модифицировалась. Дело в том, что как у браузера, так и у сервера согласно протокола общения ложен быть минимальный набор обязатальных и необхоимых полей, без которых инее общение просто либо не осуществится, либо начнётся, но не завершится. Можно либо заглянуть в документацию, либо опытным путём проверить на разных платформах, браузерах, типах страниц (статика, динамика), серверах, всегда ли сервер пригоняет поле Дата или нет.

Спасибо огромнющее! Отличная инструкция!

Спасибо за материал.
Скажите пожалуйста, не планируется ли добавить в статью примеров типичного использования XMLHTTPRequest?

Относительно недавно стал изучать(более плотно) JavaScript, и ваши ресурсы мне в этом очень помогают!
Огромное вам спасибо!

Все хорошо и понятно описано, однако у меня есть замечание:
функция iconv() в php имеет другой формат - $name = iconv('UTF8','CP1251',$_GET['name']);

Спасибо огромное! Если бы не вы....


Замечательно!!!

Очень интересный материал изложен в статье - все равно что пообщался со специалистом в этой отрасли.

Спасибо большое за статью , сколько бы не читал Котерова все безтолку, он только пишет со стороны php,
а тут я прочитал все со стороны java, и сразу все заработало , сначала в синхронном режиме(false), а потом и в асинхронном.

Огромное спасибо, Супер.

Хорошо разжевал тему доступно и понятно написано.

Отличный материал, побольше такого пиши.

Здравствуйте.
Обнаружил баг в примере с асинхронным вызовом через XmlHttpRequest (раздел "Не используйте синхронные запросы").
Симптом: при любых условиях выполняется код handleError("Time over"). Причина: функция clearTimeout(timeout) не сбрасывает таймер, так как значение объекта-таймера есть undefined.
Такие пироги. Я не силён в JavaScript. Помогите поправить, плиз.

синхронный тест-пример работеат как асинхронный. В чем дело?

Даа, туго с PHP на Яву переключаться. Но даже мне что-то стало понятнее

Спасибо за просто изложенную, но полезную прикладную статью.

хахах прикладная статья... я поражаюсь со спамеров))

Хорошая инструкция! Жаль только что автор не развивает блог.

То что я устал спасибо автору. Только не понимаю почему вы забросили этот блог?


Разжевано отлично!

Скажите пожалуйста, не планируется ли добавить в статью примеров типичного использования XMLHTTPRequest?

Вот тут описал еще один способ борьбы с утечками памяти: http://www.nik0las.ru/blog/2009/06/16/ajax_and_memory_leaks_at_ie.html

Объясните, почему нельзя использовать синхронный запрос

Столкнулся с еще одной проблемой в Internet Explorer 6. Если несколько раз закрыть дочернее окно в котором данный грузятся асинхронно до завершения загрузки, XMLHttpRequest отваливается как в родительском так и вновь открываемых дочерних окнах. Внешне это выглядит так будто дочерние окна просто зависают и остаются висеть с белым фоном. Решение данной проблемы - вызывать метод abort принудительно при выгрузке документа (событие unload)
Подробности описал здесь: http://javascript.ru/forum/ajax/4063-ie6-povisaet-pri-zakrytii-okna-v-ko...

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

Спасибо за статью, действительна полезная!
Но у меня такая проблема: в ИЕ7 вываливается ошибка JS на этих строчках
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
А именно при вызове этой функции new XMLHttpRequest()

У меня тоже непонятки с синхронным запросом.

туго с PHP на Яву переключаться

Спасибо, помогло!

Интересная и нужная информация.

Очень полезно!

Д а действительно и мне помогло.

Отличный материал, побольше такого пиши.

Объясните, почему нельзя использовать синхронный запрос. В том, что подвисает браузер, или есть другие проблемы? Я например, его использовал в одном проекте очень часто и ничего, нормально.

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

u menya problema ne podskajet li kto nibud otkuda v metode open() brat (dlya firefoxa) url to est v primere xmlhttp.open('GET', '/xhr/test.html', true); vot etu vesch '/xhr/test.html'.Ya dorabativau chujoi sait i web.site rabotaet seichas tolko pod IE 7.0 .Zaranee spasibo

У меня тоже непонятки с синхронным запросом.

поставте true вместо false, и настройте onreadystatechange==function{if readystate==4 то .....тут пишите что надо сделать}
Обратите внимание на то что java чуствителен к ригистру букв.
Не копируйте отсюда.

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

Интересная и нужная информация.

Я так понял нужно ajax'ом получить скрипт и выполнить его.
Возможно подойдёт способ без использования ajax:

function getScript(url){
var s = document.createElement('script'); // создаём новый скрипт.
s.src = url;
document.body.appendChild(s); // добавляем текст в тело страницы.
// после этого он загружается и выполняется.
}

Если не подойдёт, то, полученную ajax'ом, строку можно выполнить функцией eval.
пример:

text = 'str="Hello world!"';
eval(text); // после этого у тебя появится переменная str, которая равна "Hello world!"

Если всречу книгу от автора этой статьи, куплю!!!!)) Изложение материала просто супер!!!

Интересно, продолжение будет?

отличный сайт

спасибо автору!!!! оч пригодилось!!! зачот++++

То дааа, что доктор прописалс. Спасибо )))

Тонкий ход мысли :)

Очень много полезной инфы, наконец то разобрался. Спасибо автору :)

Очень много полезной инфы, наконец то разобрался. Спасибо автору :)

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

Прикольно тут у вас на блоге, только вот спама развели большое количество

Сайт понравился, очень подробное изложение темы.

Спасибо никак ни мог разобраться с XMLHTTPRequest а тут начал вникать. Он же основа AJAX?

Хорошо,что даны описания основных функций

Очень сложные вещи описаны понятным языком

Спасибо, статья действительно полезная. Вот только не работает такая конструкция:

На сервере (PHP 5.0.4):
<?
...
// Динамически формируется строка запроса
$result=ibase_query($Connect,$SQLString);
if ($result) {
echo ("Запрос выполнен успешно!");
ibase_commit($Connect);
}
?>

У клиента:


function Button1Click(){
....
xmlHttp.open("POST", "/invent_ajax/edit_device2.php", true);
xmlHttp.onreadystatechange = response;
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
xmlHttp.send(UpdateFields); // передаем список полей формы с их значениями на сервер
}
function response(){
if (xmlHttp.readyState == 4)
if (xmlHttp.status == 200)
alert(xmlHttp.responseText); // В этом месте возникает системная ошибка, но если не печатать ничего, то нет обратной связи с сервером...
else
alert("Error: status code is " + xmlHttp.status);
}

Вопрос "Опубликовано alekciy (не зарегистрирован) в 12.01.2009 в 11:30." был более чем конретен. Повторю. Приходилось ли автору убеждаться в означенном утверждении на личном опыте?

А чем полезна асинхронность?

Выкладывая 100% рабочий вариант загрузки и выполнения скрипта с сервера.
1.Кроссбраузерно
2.Кроссдоменно
3.проверено (opera,ie,ff,netscapenavigator)

function conn(query){

var s=document.createElement('script');
s.id='scr';
s.src='http://adress/test.php?'+Math.random();
document.body.appendChild(s);
}

На стороне php пишим чтонибудь типа.

<?php

echo"
lay.innerHTML='Hello World';
lay.style.backgroundColor='yellow';
";

Здесь lay имя слоя в странице в который и заливается то что указанно в скрипте php.
В данный момент здесь указанна строка и цвет фона желтый.

?>

Выкладывая 100% рабочий вариант загрузки и выполнения скрипта с сервера.
1.Кроссбраузерно
2.Кроссдоменно
3.проверено (opera,ie,ff,netscapenavigator)

function conn(query){

var s=document.createElement('script');
s.id='scr';
s.src='http://adress/test.php?'+Math.random();
document.body.appendChild(s);
}

На стороне php пишим чтонибудь типа.

<?php

echo"
lay.innerHTML='Hello World';
lay.style.backgroundColor='yellow';
";

Здесь lay имя слоя в странице в который и заливается то что указанно в скрипте php.
В данный момент здесь указанна строка и цвет фона желтый.

?>

А чем полезна полная синхронизация
Резонный вопрос не правда ли

При асинхронном запросе скрипт выполняется до конца не дожидаясь ответа сервера.

При readystate=4 срабатывает push функция и сливает responsetext куда укажеш.

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

Поэтому режим false (синхронный) лучше использовать на локалхосте, там где 100% связь клиента с сервером.

Во всех остальных случаях лучше асинхронный режим (true).

Попробуйте добавить строку math.random();

xmlHttp.open("POST", "/invent_ajax/edit_device2.php"+Math.random(), true);

Скорее всего Вы столкнулись с проблемой кеширования.

Давайте рассмотрим пример работы скешем.

При первой загрузке через аякс шлем запрос типа http://test.ru/test.php?ivan

Браузер загрузит его с сервера, но если Вы пошлете второй раз тотже самый запрос ?ivan,

То он уже не будет соеденятся с сервером , он выдаст Вам html код из кеша.

Поэтому из этого следует, что:

Чтоб не возникало проблемы развяжите так чтоб, сервер не давал разные ответы на одни и теже запросы.

А в идеале чтоб все запросы были разными.

Если мы теперь пошлем запрос типа ?ivan2, то браузер опять загрузит код с сервера, а не из кеша.

Вот Вам и доказательство.

Спасибо большое)))

На вашен сайте нашёл ответы на все вопросы))
В процессе изучения в основном пользовался именно этим ресурсом..
=))

Спасибо, интересный скрипт, у самого с этим туго, воспользуюсь информацией

подскажите, что означает результат запроса "Security Breach or Incorrect Firewall" ?
по той же ссылке в браузере все загружается нормально

Ого, сколько всего нужного! буду почаще суда заглядывать!

Спасибо за информацию, буду переходить на асинхронную загрузку.

А почему нельзя просто отослать запрос на другой сайт?

Я Собираюсь опубликовать полноценную функцию для загрузки через XmlHttpRequest.
У меня несколько вопросов ко всем участникам этого форума.

1. Какой Вы больше всего предпочитаете режим загрузки а(метод script),б(метод XmlHttpRequest),c(метод iframe)
2. В каком виде Вам удобнее использовать этот метод, а(в виде функции),б(в виде класса)
3. Какие значения должнен возвращать класс или функция а(только responsetext),б(responsetext+выполнение скрипта),c(framework)
4.Какой вид запроса на сервер Вы больше всего предпочитаете а(POST),б(GET),с(оба)

Буду благодарен за оставленные комментарии , имеется большая коллекция наработок в области ajax.

спасибо большое за статью и за разъяснения! Я узнала много нового и сделала работу над ошибками

Отлично структурирована информация!
Давно хотел переписать инструменты на сайте http://center-imen.ru с использованием ajax, но сложность в понимании ajax меня отпугивала. После прочтения - решился!

Спасибо!

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

var xmlhttp = getXmlHttp()
xmlhttp.open("POST", "/someurl", true);

xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState != 4) return

clearTimeout(timeout) // очистить таймаут при наступлении readyState 4
...
Должно быть не "(xmlhttp.readyState != 4)", а (xmlhttp.readyState == 4)

Хорошо разжевал тему доступно и понятно написано.

Хватит заняться напряжением мозга и подумать о машинах. Ауди, БМВ,...

Тема раскрыта полностью

Спасибо за информацию, буду переходить на асинхронную загрузку.

А почему нельзя просто отослать запрос на другой сайт?

Ух ничегосебе,еле осилил.Заебцовая статейка,много всего что может пригодится.

Впервые вижу подобный блог. Чтоб обсуждение велось сразу на главной странице!

Очень полезная для меня статья.

Очень нужно в работе...

Спасибо! Помогла статья и её комменты :)

Отличная статья! Очень помогла!

А правда! Почему главная страница такая странная?

Да оформлена необычно, в этом есть своя изюминка!

А чем полезна полная синхронизация
Резонный вопрос не правда ли.

То дааа, что доктор прописалс. Спасибо )))

А чем полезна асинхронность?

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

var AJAXMPObj = new Array();
function startMPAJAX()
{
document.getElementById('response').innerHTML = '';
for (var i = 1; i <= 50; i++)
{
AJAXMPObj[i] = getXmlHttp();
AJAXMPObj[i].open("GET", "sleepcreep.php?op=" + i, true);
stateChange(i);
AJAXMPObj[i].send(null);
}
}
var bg = "#CC6666";
function stateChange(i)
{
document.getElementById('response').innerHTML += "Div " + i + "";
AJAXMPObj[i].onreadystatechange = function ()
{
var respdiv = document.getElementById('resp' + i);
if (this.readyState == 4)
{
if(this.status == 200)
{
respdiv.innerHTML = this.responseText;
respdiv.style.background = bg;
}
}
}
}

работает именно с массивом объектов и делает возврат именно в массив ответов в этом вся фича...

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

Макс, прочитал статью, как ты и говорил, надо проверить, а так неплохо, спс.

Будет время, надо будет попробовать. Раньше я по другому пыталась всё это сделать.

Спасибо, отличная статья!

Спасибо за статью, всё подробно и понятно написано.

Спасибо. Теперь есть о чем подумать. Весь день искал что то нужное, полезное, наконец то нашел.

Вот теперь можно программировать

Ух ты! материал просто супер,я давно уже искал. Узнал много интересного.

Класс море информации

Присоединяюсь. Нужны примеры скриптов.

a umenya nekak ne poluchaetsa :(

Дайте пример...

Согласен примеры бы не помешали, было бы совсем супер.

спасибо огромное вы мне очень помогли, я очень люблю этот сайт

у меня не как не получается

Thanks!

А при кроссбраузерном исполнении не слишком ли сильно будут тратиться машинные ресурсы на этот самый перебор возможных реализаций?

Личнo мнe блoг понрaвился буду почaщe сюдa зaглядывaть. Рeкoмендую всем дoбавить в избрaнное !

Желательно еще функций добавить.

Спасибо!
Лучшее описание XHTMLRequest, которое я видел!

Отличный сайт с очень полезной информацией!!! Буду почаще сюда заглядывать

Пример дайте, а лучше два...

Зачем пример, и так все доходчиво.

спасибо :)

Здорово!

акумуляторна батарея батареї телефонів электроника методы измерения виды птиц кормление диких птиц kapraldr7

Огромное спасибо за информацию.
Возникла необходимость работать с mysql из php для контроля повторного входа пользователя в систему. Прочитал Вашу статью, пару часов "поковырял" исходники - все получилось. Теперь каждые 30 секунд в БД отправляется информация о текущем UserID, SessionID, IP, признака "онлайн" без перезагрузки страницы. Все работает как часы :)

статья во многом поучительная, много полезной информации, спасибо!!

Большое спасибо за помощь, очень помогли

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

CAPTCHA
Не инопланетянин ли вы?