Очень часто для создания объекта XMLHTTPRequest используется схема с использованием структуры try … catch из-за того, что в разных браузерах этот объект создаётся по разному. В Internet Explorer объект XMLHTTPRequest создаётся при помощи ActiveX, в то время как другие браузеры используют собственный объект XMLHTTPRequest. Схема, о которой я говорю представена ниже:
function getXMLHTTPRequest() {
try {
req = new XMLHttpRequest();
} catch(err1) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (err2) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (err3) {
req = false;
}
}
}
return req;
}
Такой метод создания имеет недостаток – функция каждый раз при отправке AJAX запроса проверяет наличие объекта XMLHTTPRequest либо объектов ActiveX, что сказывается на производительности. В этом случае оптимизировать создание объекта можно при помощи замыканий (closures). Таким образом приходим к следующему коду:
var getXMLHTTPRequest = (function(){
// массив функций
var XMLHttpFactories = [
function () {return new ActiveXObject("Microsoft.XMLHTTP")},
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
function () {return new XMLHttpRequest()}
];
var xmlhttp = null;
for (var i=XMLHttpFactories.length-1; i>=0; i--) {
try {
xmlhttp = XMLHttpFactories[i]();
}
catch (e) {
continue;
}
return XMLHttpFactories[i];
}
})();
Здесь, функция getXMLHTTPRequest инициализируется одной из функций, содержащийся в массиве XMLHttpFactories. В итоге тело функции getXMLHTTPRequest в браузере Firefox будет иметь следующий вид:
{return new XMLHttpRequest()}
Все просто, блок try … catch выполнится только один раз – при инициализации функции.
Еще один замечательный метод придумал Дастин Диаз (Dustin Diaz), его статью можно найти здесь. Суть та же, но решена она без использования замыканий:
var getXHR = function() {
var http;
try {
http = new XMLHttpRequest;
getXHR = function() {
return new XMLHttpRequest;
};
} catch(e) {
var msxml = [
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"
];
for (var i=0, len = msxml.length; i < len; ++i) {
try {
http = new ActiveXObject(msxml[i]);
getXHR = function() {
return new ActiveXObject(msxml[i]);
};
break;
} catch(e) {}
}
}
};
Здесь функция getXHR выполнит проверку только при первом вызове, во время которого она будет переназначена в зависимости от того, какой объект имеется в наличии.
Еще хочу обратить ваше внимание на функцию создания объекта XMLHTTP в библиотеке jQuery:
var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
Это самый простой способ создания объекта из всех, виденных мной. Джон Ресиг, автор этого кода, утверждает, что различные методы создания ActiveX объектов, как то MSXML2.XMLHTTP.3.0, MSXML2.XMLHTTP и Microsoft.XMLHTTP не сильно различаются между собой, поэтому используется доступный для всех версий IE метод Microsoft.XMLHTTP, что значительно сокращает код. Поэтому, если нет особых требований к производительности функции, я бы порекомендовал использовать именно этот метод.
