Browserabhängige Probleme mit XMLHttpRequest

[FONT=-moz-fixed]Hallo Forum,
habe eine Frage bezüglich der Funktion XMLHttpRequest.
Ich versuche mit JS gewisse Teile der Seite nachzuladen, allerdings scheint mein Ansatz nicht browserübergreifend zu funktionieren, nur ab Firefox 3.6, was natürlich schlecht ist.
Bis jetzt habe ich leider nicht feststellen können, was exakt das Problem ist.

Hier ist die Seite auf der das ganze zu sehen ist:
[/FONT]http://www.felix-moeller.net/neu/
[FONT=-moz-fixed]
Und der entsprechende Codeschnipsel:
( [/FONT] http://www.felix-moeller.net/neu/js/common.js [FONT=-moz-fixed] )

[CODE]
var req = null;
try{
req = new XMLHttpRequest();
} catch (ms){
try{
req = new ActiveXObject(„Msxml2.XMLHTTP“);
} catch (nonms){
try{
req = new ActiveXObject(„Microsoft.XMLHTTP“);
} catch (failed){
req = null;
}
}
}

if (req == null) 
  alert('Error creating request object!'); 

var uri = '[http://www.felix-moeller.net/neu/load/'+(n-1)+','+language](http://www.felix-moeller.net/neu/load/%27+%28n-1%29+%27,%27+language); 
//if(params!=undefined) uri += "?"+params; 
//alert("open "+uri); 
req.open("POST", uri, true); 
req.setRequestHeader("Content-type",  "application/x-www-form-urlencoded"); 
if(params!=undefined) req.setRequestHeader("Content-length",  params.length); 
req.setRequestHeader("Connection", "close"); 

/*if (isFF35()){ 
  req.onload = req.onerror = req.onabort = function(){ 
    document.getElementById('col'+n+'b').innerHTML = req.responseText; 
    hideLoader(n); 
    openMenu(cat, subcat); 
  }; 
} else {*/ 
  req.onreadystatechange = function(){ 
    switch(req.readyState) { 
      case 4: 
        if(params == undefined) { 
          var regex = /<img.*src="([a-zA-Z:/._-]*)">/; 
          var m = regex.exec(req.responseText); 
          if (m == null) { 
            document.getElementById('col'+n+'b').innerHTML =  req.responseText; 
            hideLoader(n); 
            openMenu(cat/*, subcat*/); 
          } else { 
            var s = new Array(); 
            for (i = 1; i < m.length; i++) { 
              if (m[i]!='') 
                s.push(m[i]); 
              } 
            Preloader.add(s); 
            Preloader.onFinish(function(){ 
              document.getElementById('col'+n+'b').innerHTML =  req.responseText; 
              hideLoader(n); 
              openMenu(cat/*, subcat*/); 
            }); 
            Preloader.load(); 
          } 
        } else { 
          switch (req.responseText) { 
            case 'sent_true': 
              // WIN 
              //if  (document.getElementById('box_success').style.display == 'none') { 
                new Effect.BlindUp('input_form', { duration: 0.5 }); 
                new Effect.BlindDown('box_success', { duration:  0.5, queue: 'end' }); 
              /*} else { 
                new Effect.BlindUp('box_success', { duration: 0.5 }); 
              }*/ 
            break; 
            case 'sent_false': 
              formEnable(); 
              new Effect.BlindDown('box_warning', { duration: 0.3 }); 
            break; 
            case 'sent_already': 
              formEnable(); 
              new Effect.BlindDown('box_warning_already', {  duration: 0.3 }); 
            break; 
            default: 
              alert('error! '+req.responseText); 
            break; 
          } 
        } 
      break; 

      default: 
        return false; 
      break; 
    } 
  }; 
//} 
req.setRequestHeader("Content-Type",  "application/x-www-form-urlencoded"); 
if(params==undefined) 
  req.send(null); 
else 
  req.send(params); 

[/CODE]Wie im Code zu sehen ist, habe ich eine Browserweiche für FF3.5 gehabt, allerdings erschien sie mir überflüssig, da es auch ohne funktioniert.

Wie kann man den Code optimieren, damit er browserübergreifend funktioniert?

Vielen Dank für jede Hilfe :slight_smile:

Wäre auch für jede andere Kritik dankbar.
[/FONT]

Ich verwende für AJAX-Request meist das fertig SAJAX-Paket. Siehe: Ajax Toolkit for PHP - SAJAX - Simple Ajax Toolkit by ModernMethod

Dort steht im Quellcode für die Ermittlung des im Browser zuständigen Moduls:

var msxmlhttp = new Array( 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'); for (var i = 0; i < msxmlhttp.length; i++) { try { A = new ActiveXObject(msxmlhttp[i]); } catch (e) { A = null; } }

Da fehlt der Code für den Firefox. Ich würd’ das ganze auch umdrehen, da der IE 8 das XMLHttpRequest Objekt kennt, also in etwa so:

var obj = // Das XMLHttp Objekt erzeugen window.XMLHttpRequest ? new XMLHttpRequest() : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : null;
Das ist ausreichend für 99% aller Browser (und die anderen sind so alt, dass vermutlich schon der CSS Code der seite, nicht richtig interpretiert werden kann). Ob man wirklich eine andere Version des ActiveX Objekt braucht, halte ich für fraglich, aber man kann natürlich auch den Vorschlag auf der von mir verlinkten Seite benutzen

Ich mach das noch einfacher:

[CODE]/@cc_on @if (@_win32 && @_jscript_version >= 5) if (!window.XMLHttpRequest)
window.XMLHttpRequest = function() { return new ActiveXObject(‚Microsoft.XMLHTTP‘) }
@end @
/

var xhr = new XMLHttpRequest(); //Opera, Firefox, Internet Explorer > 5 usw.[/CODE]

Naja, ob’s einfacher ist weiß ich nicht, es sieht zumindest nicht schöner aus.

Die Frage in dem Fall ist aber auch, ob das zusätzliche jscript nicht den IE u.U. bremst, auch wenn es an sich natürlich sauberer wirkt, vor Standardkonformen Browsern den Code zu verstecken. Wobei in deinem Code natürlich noch abgefragt werden muss, ob der Browser (!IE) window.XMLHttpRequest kennt.

Und das ganze passiert einmalig beim Parsen. Danach kennt er XMLHttpRequest und es muss nicht immer neu getestet werden.

Wenn man jedesmal ein neues Objekt erzeugt ist das wohl wahr. Ich nutze eine AJAX Klasse, in der ich ein XHR Objekt immer wieder verwende, da ja sowieso die Anzahl der parallelen Requests stark begrenzt ist.

Finde ich persönlich nicht so toll. Pro Request ein neues Objekt, so ist es auch gedacht.

Wieso sollte das so gedacht sein? Ich seh in den Specs keinen Hinweis darauf, dass man ein Objekt das man ohne Probleme wieder verwerten kann wegwerfen soll.

Das kann man machen, aber ich verwende für einen String auch nicht immer das selbe String-Objekt.

Sehr schlechter Vergleich. Üblicherweise wird ein Stringobjekt extrem selten verwendet, da ein String auch ein primitiver Datentyp ist. Zumal du den Wert eines Stringobjektes auch nicht mehr ändern kannst. Die Methoden des Stringobjektes erzeugen meistens ein neues Stringobjekt.

Aber was heißt nicht immer das selbe Objekt? Wenn du ein Objekt hast, das eine bestimmte Aufgabe erfüllen soll, dann reicht ein Objekt für diese Aufgabe und du musst nicht jedesmal ein neues Objekt erstellen, das ist ist OOP

Sicher ist String auch ein Datentyp, aber es Strings werden als Objekte im Speicher abgelegt und das Änderungen an einem String-Objekt ein neues Objekt erzeugen ist mir auch bewusst.

Für mich ist jeder Request eben eine neue Aufgabe und eben drum erzeuge ich ein neues. Das ist aber letztendlich Ansichtssache.

Nee, das ist OOP.