Deprecated: Function set_magic_quotes_runtime() is deprecated in /DISK2/WWW/blue-team.org/bcblog/textpattern/lib/txplib_db.php on line 14 Bc. BLOG: AJAX

Úterý březen 31, 2009

Zpropadený Firefox aneb synchronizace u XMLHttpRequest

· rubrika Clanky · kategorie

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 ) a já potřeboval aby to fungovalo ve všech nejpoužívanějších prohlížečích.

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:

  1. /**
  2.  * Trida pro vykonavani Http pozadavku (AJAX)
  3.  */
  4.  function HttpClient() { } // HTTPCLIENT CLASS
  5.  HttpClient.prototype = {
  6.   // GET nebo POST
  7.   request_type:'GET',
  8.   // synchroni a nebo asynchroni pozadavek (synchroni nefunguje ve firefoxu 3 neco )
  9.   request_async:true,
  10.   // instance
  11.   xmlhttp:false,
  12.   //kde se zobrazi vysledek
  13.   where_show_content:'',
  14.  
  15.   // inicializace -> vytvoreni XMLHttpRequest
  16.   init:function() {
  17.     try {
  18.       // Mozilla / Opera / Safari
  19.       this.xmlhttp = new XMLHttpRequest();
  20.     }
  21.     catch (e){
  22.       // IE (snad vsechny nejpouzivanejsi verze)
  23.       var MSXML = new Array('MSXML2.XMLHTTP.5.0',
  24.          'MSXML2.XMLHTTP.4.0',
  25.          'MSXML2.XMLHTTP.3.0',
  26.          'MSXML2.XMLHTTP',
  27.          'Microsoft.XMLHTTP');
  28.       var ok = false;
  29.       for (var i=0;i < MSXML.length && !ok; i++){
  30.         try {
  31.           this.xmlhttp = new ActiveXObject(XMLHTTP_IDS[i]);
  32.           success = true;
  33.         }
  34.         catch (e){}
  35.       }
  36.       if (!success){
  37.         alert('Váš prohlížeč napodporuje AJAX!');
  38.       }
  39.     }
  40.   },
  41.   
  42.   //provedeni pozadavku
  43.   request: function(url){
  44.     if (!this.xmlhttp){
  45.       this.init();
  46.     }
  47.     this.xmlhttp.open(this.request_type,url,this.async);
  48.     this.xmlhttp.send(null); //pro posilani POST pozadavku
  49.    
  50.     //zobrazení loadingu
  51.     document.getElementById(this.where_show_content).innerHTML = '<img src=\"images/loading.gif\" alt="" />';
  52.    
  53.     //zpristupneni this ve funkci
  54.     var self = this;
  55.     this.xmlhttp.onreadystatechange = function(){
  56.       switch(self.xmlhttp.readyState) {
  57.       case 0:
  58.         break;
  59.       case 1:
  60.         break;
  61.       case 2:
  62.         break;
  63.       case 3:
  64.         break;
  65.       case 4:
  66.         if (self.xmlhttp.status == 200) {
  67.           document.getElementById(self.where_show_content).innerHTML = self.xmlhttp.responseText;
  68.         }else {
  69.           alert('HTTP Chyba při vykonávání dotazu: ' + '[' + self.xmlhttp.status + ']' + ' ' + self.xmlhttp.statusText);
  70.         }
  71.         break;
  72.       }
  73.     }
  74.   }
  75.  }
  76.  
  77. /**
  78. * ukazka volani tridy
  79. */
  80. var client = new HttpClient();
  81. client.async = true; //asynchroni mod
  82. client.where_show_content = 'main-box'; //kde zobrazit vysledek
  83. client.request('localhost/diplomka?pg=ajax'); //url pozadavku

20:00 — Komentář Stálý odkaz



XHTML 1.0 Strict - CSS