XMLHttp Request object maken
Op het Internet kun je veel tutorials vinden hoe je AJAX functionaliteit kunt realiseren door een XMLHttp Request te maken. Een iemand is ermee begonnen en al snel kopieerden andere gebruikers de code. Ook andere tutorials schrijvers namen de code over, zonder te weten wat de code precies betekent. Volgens mij kan juist die code wel wat tuning gebruiken!
Dit is de code die je vaak terug ziet:
-
function createRequestObject() {
-
var request;
-
var browser = navigator.appName;
-
if (browser == "Microsoft Internet Explorer")
-
{ request = new ActiveXObject("Microsoft.XMLHTTP"); }
-
else { request = new XMLHttpRequest (); }
-
-
return request;
-
}
Het navigator object bevat informatie over de browser, maar dit is zeer onbetrouwbaar. Deze verschilt nog wel eens per browser release en deze gegevens zijn te manipuleren. Het beter is om te controleren of er ondersteunig is voor het XMLHttpRequest object. Microsoft's IE heeft dit object niet, maar een ActiveX variant. Firefox, Safari en Opera hebben dit object wel.
Vanaf versie 5 had Internet Explorer ondersteuning voor XML, met de ActiveX library MSXML. Deze library bevat het XMLHttp request object. Dit object werd snel populair en Mozilla nam dit object over (niet andersom!) en implementeerde dit in Firefox. Het object kreeg wel een andere naam, XMLHttpRequest. Safari en Opera namen later de implementatie van Firefox over.
Een XMLHttp request object maken voor IE gaat dus op deze manier:
-
var request = new ActiveXObject("Microsoft.XMLHttp");
Een betere variant op de bovengenoemde createRequestObject() functie staat hieronder.
-
function createRequestObject() {
-
var request;
-
if(window.XMLHttpRequest)
-
{ request = new XMLHttpRequest(); }
-
else if(window.ActiveXObject)
-
{ request = new ActiveXObject("Microsoft.XMLHTTP"); }
-
return request;
-
}
Deze variant zie je ook veel terug en is beter dan de eerste, omdat deze niet een browser check doet. Het is wel voor verbetering vatbaar, daarmee refereer ik naar het ActiveXObject.
Door de jaren heen heeft Microsoft aanpassingen aangebracht aan het MSXML library, maar ook aan XMLHttp. Hierdoor zijn verschillende versies ontstaan, ieder met snelheids verbeteringen en betere stabiliteit. Hieronder staat een lijst met release versies.
- Microsoft.XMLHttp
- MSXML2.XMLHttp
- MSXML2.XMLHttp.3.0
- MSXML2.XMLHttp.4.0
- MSXML2.XMLHttp.5.0
Het is dus het beste om de nieuwste versie te nemen, maar zoals je al in de code zag zie je dat niet gebeuren. Men neemt gauw de eerste versie (uit onzekerheid? onwetenheid? of simpelweg plagiaat?) van XMLHttp, terwijl we juist paar versies verder zijn! De enige manier om erachter komen welke versie de gebruiker heeft, is door alle versies aan te maken en kijken welk object we kunnen maken. Bij het mislukking zal de ActiveX control een exception gooien. Handig, want we kunnen dan een try-catch blok gebruiken!
-
function createRequestObject() {
-
var request;
-
-
if(window.XMLHttpRequest)
-
{ request = new XMLHttpRequest(); }
-
else if(window.ActiveXObject) {
-
-
var ie_versions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0",
-
"MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp",
-
"Microsoft.XMLHttp"];
-
-
for(var i=0; i <ie_versions.length; i++) {
-
try {
-
request = new ActiveXObject(ie_versions[i]);
-
}
-
catch (error) {}
-
}
-
}
-
-
return request;
-
-
}
In de array hebben we alle versies erin gezet, met de nieuwste als eerste. In de try-catch blok loop-en we door de array. Mocht de betreffende versie niet bestaan, dan gebeurt er door de catch blok helemaal niets. Dan loop-en we gewoon verder naar de volgende versie. Zo krijgen we de beste XMLHttp versie!
Deze nieuwe versie van de functie createRequestObject() is beter dan de andere versies, omdat deze het beste eruit haalt uit Internet Explorer. Een snelle check op verschillende AJAX toolkits onthult dat vaak de oude manier wordt gebruikt. Onder deze toolkits bevindt mijn lievelings Javascript library Prototype. Ik moet gauw met Sam Stephenson praten.
Volg Scriptorama via RSS!
Reageer ook!
Hey Tri,
Wat is precies de performance impact van het proberen te creeren (in the worstcase scenario) van 5 ActiveX objecten? Is het ook wel verstandig, compatabiliteits wijs, om in een script te proberen 5 verschillende versies te proberen gebruiken?
MSIE7 zal overigens native support voor het XmlHttpRequest object hebben, op dezelfde manier dat Mozilla en Opera dat implementeren. AJAX gebruik zal dan niet meer onderhevig zijn aan de ActiveX security settings.
Door Mathieu Kooiman
op 04.05.06 @ 8:03 am | Permalink
Zelfs veelgebruikte JavaScript libraries als Prototype maken geen gebruik van de nieuwere versies van XMLHttp. Ik had eigenlijk beter verwacht.
Door Edwin V.
op 04.05.06 @ 10:46 am | Permalink
De performance impact heb ik niet gemeten, maar ik verwacht geen opzienbare performance verlies. Mochten de nieuwere versies niet aangemaakt worden, dan wordt Microsoft.XMLHttp altijd aangemaakt. Mits je >= IE 5.0 hebt. Geen zorgen dus over compatabiliteit.
Door Tri Pham
op 04.05.06 @ 3:43 pm | Permalink
Hallo,
Mijn functie voor AjaxLoad ziet er altijd zo uit:
function AjaxLoad(dest, selout)
{
idfile = selout;
try
{
xmlhttp = window.XMLHttpRequest?new XMLHttpRequest():
new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
//
}
xmlhttp.onreadystatechange = triggered;
dest = dest+'&f='+selout;
xmlhttp.open("GET", dest);
xmlhttp.send(null);
}
Deze werkt ook in alle browsers, maar is dit wel de goede methode? :)
Door Riny van Tiggelen
op 04.23.06 @ 9:51 am | Permalink
Dat is precies de 'oude' manier. "Never change a winning team." Het werkt, dus waarom zou je het veranderen? Ik heb alleen aangegeven dat het iets efficienter kan :)
Door Tri Pham
op 04.23.06 @ 9:56 am | Permalink
Hallo Tri,
Allereerst top dat je zoveel artikelen schrijft! Alleen even een opmerking bij dat laatste voorbeeld met die for loop klopt niet, want hij loopt gewoon door en pakt uiteindelijk juist de meest oude versie omdat de try catch in de loop zelf zit vangt hij hem ja nergens op dus hij breekt de loop niet bij een goeie versie.
Succes,
Vince
Door Vincent Meens
op 08.08.07 @ 1:21 pm | Permalink
Ja die for loop klopt niet!, daar moet inderdaad een break regeltje in.
Door Bart
op 04.24.08 @ 2:41 pm | Permalink
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>