Úterý březen 31, 2009
Zpropadený Firefox aneb synchronizace u XMLHttpRequest
· rubrika Clanky · kategorie AJAX
Je tomu teprve pár týdnů, kdy jsem se začal věnovat AJAXu, protože jsem ho potřeboval použít v mé diplomové práci. V ní jsem potřeboval zavolat jeden skript a po jeho dokončení ho znovu zavolat, jen s jinými parametry. Výsledky běhu skriptu (tzn. proběhlo to ok, nastala nějaká chyba), jsem chtěl zobrazovat do různých objektů na XHTML stránce. Napsal jsem si tedy tři funkce na práci s XMLHttpRequest, kde jsem v jedné z nich použil následující kód:xmlhttp.open("GET",url,false);
Třetí parametr metody open říká, zda se má čekat na odpověď či nikoliv tzn. zda se použije synchroní nebo asynchroní mód.
Celé to funguje tak, že při synchroním přenosu, dojde k vytvoření nového vlákna přičemž původní je pozastaveno (tzn. je pozastavena veškerá interaktivita na straně klienta). V nově vytvořeném vláknu dojde k vyřízení požadavku a po jeho skončení se opět aktivuje vlákno původní a to zpracuje získaný výsledek. V druhém případě se nové vlákno nevytváří a uživatel tak může klidně dále využívat interaktivních stránek a po dokončení požadavku, je jeho výsledek zpracován.
Vše fungovalo dobře v Opeře 9.64, tak jsem to vyzkoušel i v IE 8 a následně ve Firefoxu 3.0.8. Jak jsem překvapivě zjistil, v mé nynější (a nejnovější) verzi Firefoxu synchroní přenos nefunguje (na internetu jsem se po té našel informace o nějakém bugu, ale už nevím kde
Druhou metodou lze poslat více požadavků najednou a současně čekat na jejich vyřízení. Tuto variantu jsem nechtěl použít z důvodu toho, že skript na který se odkazuji exportuje data z databáze a importuje do jiné. Mnohdy jde i o statisíce záznamů a tak jsem nechtěl server moc zatěžovat vícenásobným spuštěním skriptu. Bohužel jsem po několika hodinách dospěl k názoru, že je to jediné možné řešení.
Pokud například chceme výsledky zobrazovat v různých objektech na (X)HTML stránce, tak jako já v diplomce, stačí k tomu použít třídu v JavaScriptu, kde si dokážeme uchovat jednotlivé instance XMLHttpRequestu a id objektu (bez použití třídy by jsme o ně přišli). Napsal jsem si tak vlastní třídu, kterou můžete najít níže. Předem bych chtěl schovívavost ke kódu. Vím, že mnou napsaná třída nesplňuje požadavky na znovupoužitelnost, až budu mít více času upravím ji
Zdrojový kód:
- /**
- * Trida pro vykonavani Http pozadavku (AJAX)
- */
- function HttpClient() { } // HTTPCLIENT CLASS
- HttpClient.prototype = {
- // GET nebo POST
- request_type:'GET',
- // synchroni a nebo asynchroni pozadavek (synchroni nefunguje ve firefoxu 3 neco
) - request_async:true,
- // instance
- xmlhttp:false,
- //kde se zobrazi vysledek
- where_show_content:'',
- // inicializace -> vytvoreni XMLHttpRequest
- init:function() {
- try {
- // Mozilla / Opera / Safari
- this.xmlhttp = new XMLHttpRequest();
- }
- catch (e){
- // IE (snad vsechny nejpouzivanejsi verze)
- var MSXML = new Array('MSXML2.XMLHTTP.5.0',
- 'MSXML2.XMLHTTP.4.0',
- 'MSXML2.XMLHTTP.3.0',
- 'MSXML2.XMLHTTP',
- 'Microsoft.XMLHTTP');
- var ok = false;
- for (var i=0;i < MSXML.length && !ok; i++){
- try {
- this.xmlhttp = new ActiveXObject(XMLHTTP_IDS[i]);
- success = true;
- }
- catch (e){}
- }
- if (!success){
- alert('Váš prohlížeč napodporuje AJAX!');
- }
- }
- },
- //provedeni pozadavku
- request: function(url){
- if (!this.xmlhttp){
- this.init();
- }
- this.xmlhttp.open(this.request_type,url,this.async);
- this.xmlhttp.send(null); //pro posilani POST pozadavku
- //zobrazení loadingu
- document.getElementById(this.where_show_content).innerHTML = '<img src=\"images/loading.gif\" alt="" />';
- //zpristupneni this ve funkci
- var self = this;
- this.xmlhttp.onreadystatechange = function(){
- switch(self.xmlhttp.readyState) {
- case 0:
- break;
- case 1:
- break;
- case 2:
- break;
- case 3:
- break;
- case 4:
- if (self.xmlhttp.status == 200) {
- document.getElementById(self.where_show_content).innerHTML = self.xmlhttp.responseText;
- }else {
- alert('HTTP Chyba při vykonávání dotazu: ' + '[' + self.xmlhttp.status + ']' + ' ' + self.xmlhttp.statusText);
- }
- break;
- }
- }
- }
- }
- /**
- * ukazka volani tridy
- */
- var client = new HttpClient();
- client.async = true; //asynchroni mod
- client.where_show_content = 'main-box'; //kde zobrazit vysledek
- client.request('localhost/diplomka?pg=ajax'); //url pozadavku
20:00
—
Komentář
—
Stálý odkaz