Javascript.RU

XMLHTTPRequest

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/ajax-xmlhttprequest.

Объект XMLHTTPRequest - низкоуровневая основа большинства AJAX-приложений. Знание его методов, свойств и особенностей не только помогает писать приложения на низком уровне с минимумом javascript-кода, но и позволяет понять, что происходит внутри фреймворков, которые, увы, часто несовершенны или тянут много лишнего.

Основные методы для посылки запросов XMLHttpRequest:

  • open(Method, Url, async)
  • send(data)
  • onreadystatechange

Правильная последовательность open/onreadystatechange/send:

req.open("GET", url, true)
req.onreadystatechange = handler
req.send(null)

Методы для манипуляции заголовками:

  • setRequestHeader()
  • getResponseHeader()
  • getAllResponseHeaders()

Обрыв соединения осуществляет метод

  • abort()

Ответ сервера находится в

  • responseText
  • responseXML
  • status
  • statusText

Причем responseXML заполняется только в случае, когда Content-Type с сервера имеет значение text/xml (кроме overrideMimeType-метода, но он есть только в Firefox).

Краткая сводка плюсов и минусов

  • Возможна синхронная передача (хотя и подвешивает браузер)
  • Полный контроль над заголовками
  • Можно отсылать документы из браузера в виде файлов, составляя POST-запрос вручную
  • В явном виде выдает ошибки коммуникации
  • Ограничение безопасности при помощи same origin policy
  • Невозможна отправка файлов, выбранных в форме
  • Утечки памяти при неправильном применении в старых IE

Пример небольшой функции getUrl, которая делает запросы:

function getXmlHttp(){
	try {
		return new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			return new ActiveXObject("Microsoft.XMLHTTP");
		} catch (ee) {
		}
	}
	if (typeof XMLHttpRequest!='undefined') {
		return new XMLHttpRequest();
	}
}

// Получить данные с url и вызывать cb - коллбэк c ответом сервера 
function getUrl(http://javascript.ru/forum/url, cb) { 
	var xmlhttp = getXmlHttp();
	// IE кэширует XMLHttpRequest запросы, так что добавляем случайный параметр к URL
	// (хотя можно обойтись правильными заголовками на сервере)
	xmlhttp.open("GET", url+'?r='+Math.random());
	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4) {
			cb(
			xmlhttp.status, 
			xmlhttp.getAllResponseHeaders(), 
			xmlhttp.responseText
			);
		}
	}
	xmlhttp.send(null);
}

Более подробно о свойствах и применении XMLHTTPRequest - на http://xmlhttprequest.ru


Автор: Павлик (не зарегистрирован), дата: 27 августа, 2008 - 18:04
#permalink

Замечательная статья!! Автору респект!


Автор: Гость (не зарегистрирован), дата: 2 октября, 2008 - 17:03
#permalink

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


Автор: orange, дата: 25 января, 2009 - 01:13
#permalink

если мне не изменяет память то это можно сделать, только если объект создан с использованием ActiveXObject, то есть в 5, 6 версии IE, а объект XMLHTTPRequest (то есть это все остальные браузеры, включая и IE 7>) не позволяет отправлять запросы на другие сервера - политика безопасности.
Если не прав - поправьте


Автор: Злата (не зарегистрирован), дата: 16 декабря, 2008 - 00:48
#permalink

естественно, почему бы и нет


Автор: Вадим (не зарегистрирован), дата: 16 января, 2009 - 16:53
#permalink

краткость сестра толанта, данный случай к коду.


Автор: B@rmaley.e><e (не зарегистрирован), дата: 22 сентября, 2009 - 17:43
#permalink

Контроль над заголовками далеко не полный. Попробуйте кроссбраузерно передать рефер.


Автор: bandolero, дата: 5 февраля, 2010 - 10:47
#permalink

Подсветка синтаксиса делает зеленым все, что следует за двумя слэшами (//). Поэтому в следующей строке все, что находится правее "http:", отображается зеленым цветом:
function getUrl(http://javascript.ru/forum/url, cb) {


Автор: HelpeR, дата: 10 марта, 2010 - 21:20
#permalink

Здравствуйте Илья Кантор. Хотел спросить на данный момент все браузеры (IE7, 8 FF2, 3, Opera 9, 10) сами автоматически удаляют XMLHttpRequest после получения данных с сервера и никакой утечки памяти не происходит?
И еще хотел спросить, не могли бы вы уточнить на счет этого (Можно отсылать документы из браузера в виде файлов, составляя POST-запрос вручную).
Заранее благодарен!


Автор: Илья Кантор, дата: 10 марта, 2010 - 23:48
#permalink

В общем, все почти ок с утечками. XMLHTTPRequest может формировать заголовки аналогичные тем, которые формирует браузер при посылке файла и тем самым пересылать как бы файл на сервер.


Автор: HelpeR, дата: 11 марта, 2010 - 21:20
#permalink

Значит именно таким образом происходит ajax загрузка файлов на сервер? Т.е. путь к файлу считывается с input type="file" и виде заголовка отправляется на сервер?


Автор: nikonian (не зарегистрирован), дата: 15 апреля, 2010 - 15:13
#permalink

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


Автор: Гость (не зарегистрирован), дата: 10 августа, 2010 - 13:39
#permalink

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

//ссылка на объект XmlHttpRequest
var xmlHttp = createXmlHttpRequestObject();
//создаем экземпляр XmlHttpRequest
function createXmlHttpRequestObject()
{
	//для хранения ссылки на XmlHttpRequest
	var xmlHttp;
	//следующий код работает во всех браузерах
	//кроме IE6 и более ранних версиях
	try //обработка ошибок
	{
		//попытаться создать объект XmlHttpRequest
		xmlHttp = new XmlHttpRequest();
	}
	catch(e)
	{
		//событие происходит если используется IE6 или более раняя версия
		var XmlHttpVersions = new Array("MSXML2.XMLHHTP.6.0",
										"MSXML2.XMLHHTP.5.0",
										"MSXML2.XMLHHTP.4.0",
										"MSXML2.XMLHHTP.3.0",
										"MSXML2.XMLHHTP",
										"Microsoft.XMLHHTP");
		//попоробовать все возможные версии (prog id), пока что то не подойдет =)
        for (var i = 0; i < XmlHttpVersions.length && !xmlHttp; i++)
        {
        	try
        	{
          		xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
        	}
        	catch(e){}
        }
	}
	if (!xmlHttp)
	{
  		alert("Ошибка создания объекта XmlHttpRequest");
	}
	else return xmlHttp;
}

Автор: Гость (не зарегистрирован), дата: 10 августа, 2010 - 15:08
#permalink

Пардон... сам разобрался... Оказывается нужно XMLHttpRequest а не XmlHttpRequest


Автор: Гость (не зарегистрирован), дата: 6 ноября, 2010 - 23:53
#permalink

Все примеры только на стороне клиента, а как на сервере принимать данные, в какую переменную записывается отправляемое сообщение. В $_GET ?


Автор: B@rmaley.e><e, дата: 7 ноября, 2010 - 20:50
#permalink

Для сервера такой запрос идентичен обычному. Если метод запроса - GET, то значения нужно искать там, где находятся переменные GET запросов, если POST, то там, где им самое место.


Автор: Серега Kamillorn (не зарегистрирован), дата: 23 ноября, 2010 - 20:25
#permalink

Я делаю так:

var url = "agregator.php?param1="+значение1+"&param2="+значение2+"&random=" + Math.random(); // random (случайное число) - чтобы не было глюков с кешированием
		

		request.open("GET", url, true);
		request.onreadystatechange = updatePage;
		request.send(null);
		function updatePage()
		{
                         if (request.readyState == 4)
			if (request.status == 200)
			{
				// Вызов функции обработки ответа и передача ей ответа
			tmp=request.responseText; // тут хранится ответ от agregator.php
				
			delete request;
					
			
				
			}
			else
			{
				alert("Сервер не ответил");
			}
                
                 }

Автор: mister_maxim, дата: 19 марта, 2011 - 20:22
#permalink

Серега Kamillorn, а как в прочем и автор, а зачем вы используете Math.random() с GET запросом, на мой взгляд коли не хотите кэширования, то уж сразу посылайте POST запросом, и браузеру не будет морока запросы с Math.random циферки хранить.


Автор: Евгенннн (не зарегистрирован), дата: 18 октября, 2011 - 14:20
#permalink

Я только начинающий web-программист, и мне многое не понятно в этой статье
Например: для чего нужен метод onreadystatechange, тут этого не объяснено;
Как работают методы setRequestHeader() getResponseHeader() getAllResponseHeaders()
Все таки надо понимать что на ваш сайт будут залазить совсем новички, чтобы пополнять свои знания, поэтому нужно более подробно пояснять методы объектов


Автор: Ramzil_Nixon (не зарегистрирован), дата: 20 ноября, 2011 - 21:33
#permalink

Дааа. Тут каждый регистр важен...


Автор: allergencore, дата: 28 февраля, 2012 - 18:52
#permalink

заметил такую бредятину(? может, это и к лучшему): у XMLHttpRequest существует что-то вроде "блек-листа" для заголовков. Делая запрос на пхп-шник:

<?php
//... <- setting up headers :D
print_r($_SERVER);
?>

обнаружил что Accept-Charset и еще некоторые заголовки игнорируются при отправке из жабы...
P.S. Народ будьте аккуратнее при веб-серфе в рунете, быдлокодеры совсем офигели - tsr.boot virus словил вчера даже не понял как... но выкурить проблемы не было, ибо это быдлокодеры...


Автор: Дюк (не зарегистрирован), дата: 29 февраля, 2012 - 18:00
#permalink

Больше примеров, пожалуйста! Что изменится, если сделать запрос методом POST? Как сформировать отправляемые данные, например, из ? Как и куда поступают отправленные данные?


Автор: keithbently (не зарегистрирован), дата: 22 мая, 2012 - 12:58
#permalink

Через XMLHTTPREQUEST можно залить файл на сервер.
Нет ну серьёзно:D скора на хабре постну


Автор: Гость (не зарегистрирован), дата: 21 августа, 2012 - 16:24
#permalink

Не подскажете какой-нибудь способ обойти политику безопасности?


Автор: Гость (не зарегистрирован), дата: 11 октября, 2012 - 21:14
#permalink

Автору +5!Прочитал курс новых и старых статей, обычно для изучения технология надо знать английский язык, а здесь читаю все на русском, кратко, внятно и главное ДОСТУПНО!!!Теперь буду более правильно делать свои скрипты.


Автор: Гость (не зарегистрирован), дата: 13 апреля, 2018 - 06:34
#permalink

"более правильно" = "правильнее"


Автор: Гость (не зарегистрирован), дата: 4 апреля, 2013 - 15:04
#permalink

onreadystatechange это же свойство а не метод? Или я не прав?


Автор: wbrframe, дата: 14 июня, 2013 - 21:18
#permalink

Столкнулся с одной проблемой, буду благодарен за дельный совет.
Использую функцию $.ajax для отправки запросов и в определенной ситуации нужно оборвать соединение через abort(). Это благополучно и делаю, но к сожалению abort() тригерит error(). Этому как раз и пытаюсь отучить.

Пробовал вот так:

$.ajax({
   error: function( jqXHR, textStatus, errorThrown )
   {
       if( jqXHR == 'abort' ) 
       {
           return;
       }
       else
       {
           // show user friendly error message
       }
   }
});

К сожалению эта проверка по какой-то причине не всегда срабатывает.


Автор: pol (не зарегистрирован), дата: 5 сентября, 2013 - 16:31
#permalink

Можно спросить? В getXmlHttp() мы сначала пытаемся поднять ActiveXObject "Msxml2.XMLHTTP", потом "Microsoft.XMLHTTP" и лишь когда не получается - стандартно вызываем XMLHttpRequest(). Это отражает некий табель о рагах?
(я привык видеть XMLHttpRequest на первом месте).


 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние темы на форуме
Forum