2010-03-31 7 views
33

Quel est le moyen le plus simple et le plus sûr pour récupérer l'objet XmlHttpRequest qui fonctionne dans tous les navigateurs? Sans bibliothèques supplémentaires. Existe-t-il un extrait de code que vous utilisez souvent?Meilleure façon de récupérer XmlHttpRequest navigateur croisé

P.S. Je sais qu'il y a énormément d'exemples sur le net, mais c'est précisément la raison pour laquelle je pose la question: il y a trop d'exemples différents, et je veux juste quelque chose de simple et de prouvé.

jQuery et d'autres bibliothèques N'EST PAS une option. Why does jquery leak memory so badly?

+1

Je sais que vous dites "sans utiliser des bibliothèques externes" mais la réponse est * encore * "utiliser jQuery". C'est moins de 25k gzipped. – cletus

+0

jQuery est utilisé parce qu'il est simple et facile –

+1

Une autre grande bibliothèque est prototype. Cependant, pourriez-vous expliquer pourquoi vous ne voulez pas utiliser une bibliothèque? Ils pourraient rendre votre vie beaucoup plus facile .. –

Répondre

59

Pendant que je vous conseille d'utiliser une bibliothèque complète pour rendre l'utilisation plus facile, ce qui rend les requêtes AJAX peut être assez simple dans les navigateurs modernes:

var req = new XMLHttpRequest(); 
req.onreadystatechange = function(){ 
    if(this.readyState == 4){ 
     alert('Status code: ' + this.status); 
     // The response content is in this.responseText 
    } 
} 
req.open('GET', '/some-url', true); 
req.send(); 

L'extrait suivant est un extrait plus avancé basé sur un extrait de quirksmode.org et supporte même très anciens navigateurs (Internet Explorer de plus de 7):

function sendRequest(url,callback,postData) { 
    var req = createXMLHTTPObject(); 
    if (!req) return; 
    var method = (postData) ? "POST" : "GET"; 
    req.open(method,url,true); 
    // Setting the user agent is not allowed in most modern browsers It was 
    // a requirement for some Internet Explorer versions a long time ago. 
    // There is no need for this header if you use Internet Explorer 7 or 
    // above (or any other browser) 
    // req.setRequestHeader('User-Agent','XMLHTTP/1.0'); 
    if (postData) 
     req.setRequestHeader('Content-type','application/x-www-form-urlencoded'); 
    req.onreadystatechange = function() { 
     if (req.readyState != 4) return; 
     if (req.status != 200 && req.status != 304) { 
//   alert('HTTP error ' + req.status); 
      return; 
     } 
     callback(req); 
    } 
    if (req.readyState == 4) return; 
    req.send(postData); 
} 

var XMLHttpFactories = [ 
    function() {return new XMLHttpRequest()}, 
    function() {return new ActiveXObject("Msxml3.XMLHTTP")}, 
    function() {return new ActiveXObject("Msxml2.XMLHTTP.6.0")}, 
    function() {return new ActiveXObject("Msxml2.XMLHTTP.3.0")}, 
    function() {return new ActiveXObject("Msxml2.XMLHTTP")}, 
    function() {return new ActiveXObject("Microsoft.XMLHTTP")} 
]; 

function createXMLHTTPObject() { 
    var xmlhttp = false; 
    for (var i=0;i<XMLHttpFactories.length;i++) { 
     try { 
      xmlhttp = XMLHttpFactories[i](); 
     } 
     catch (e) { 
      continue; 
     } 
     break; 
    } 
    return xmlhttp; 
} 
+0

Nous utilisons déjà jQuery, mais il fuit la mémoire, ce qui est crucial dans notre cas. Merci pour l'extrait, je vais l'essayer. –

+0

Quel navigateur utilise Msxml3? Je ne l'ai pas vu auparavant. –

+0

Tout système ne disposant pas de Msxml6 (que Microsoft.XMLHTTP appellera). Je sais qu'au moins Windows 2000 SP4 a Msxml3 disponible :) – Wolph

4

pas 100% certains de votre question - mais si vous demandez la fonction de re tourner une instance croix navigateur XMLHTTP - nous avons utilisé cela dans notre bibliothèque ajax natif depuis des années - et jamais un problème dans tout navigateur

function getXMLHTTP() { 
    var alerted; 
    var xmlhttp; 
    /*@cc_on @*/ 
    /*@if (@_jscript_version >= 5) 
    // JScript gives us Conditional compilation, we can cope with old IE versions. 
    try { 
     xmlhttp=new ActiveXObject("Msxml2.XMLHTTP") 
    } catch (e) { 
    try { 
     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP") 
    } catch (E) { 
     alert("You must have Microsofts XML parsers available") 
    } 
    } 
    @else 
     alert("You must have JScript version 5 or above.") 
     xmlhttp=false 
     alerted=true 
    @end @*/ 
    if (!xmlhttp && !alerted) { 
     // Non ECMAScript Ed. 3 will error here (IE<5 ok), nothing I can 
     // realistically do about it, blame the w3c or ECMA for not 
     // having a working versioning capability in <SCRIPT> or 
     // ECMAScript. 
     try { 
      xmlhttp = new XMLHttpRequest(); 
     } catch (e) { 
      alert("You need a browser which supports an XMLHttpRequest Object") 
     } 
    } 
    return xmlhttp 
} 
13

Comme demandé, simple et éprouvée à travailler:

function Xhr(){ /* returns cross-browser XMLHttpRequest, or null if unable */ 
    try { 
     return new XMLHttpRequest(); 
    }catch(e){} 
    try { 
     return new ActiveXObject("Msxml3.XMLHTTP"); 
    }catch(e){} 
    try { 
     return new ActiveXObject("Msxml2.XMLHTTP.6.0"); 
    }catch(e){} 
    try { 
     return new ActiveXObject("Msxml2.XMLHTTP.3.0"); 
    }catch(e){} 
    try { 
     return new ActiveXObject("Msxml2.XMLHTTP"); 
    }catch(e){} 
    try { 
     return new ActiveXObject("Microsoft.XMLHTTP"); 
    }catch(e){} 
    return null; 
} 

Collapsing en une seule ligne, nous obtenons:

function Xhr(){ 
    try{return new XMLHttpRequest();}catch(e){}try{return new ActiveXObject("Msxml3.XMLHTTP");}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0");}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0");}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP");}catch(e){}try{return new ActiveXObject("Microsoft.XMLHTTP");}catch(e){}return null; 
} 
+2

Selon le centre de développement IE, et je cite, "Pour soutenir les versions IE antérieures à IE7, vous pouvez utiliser:" return new ActiveXObject (" MSXML2.XMLHTTP.3.0 ") – andreszs

+0

@Andrew, Oui, le lien est ici: https://msdn.microsoft.com/en-us/library/ms535874(v=vs.85).aspx#code-snippet-4. Les vieux navigateurs sont vraiment des maux de tête, bien que ces jours-ci pour des projets personnels, je ferais probablement tout simplement 'new XMLHttpRequest();'. – Pacerier

1

une façon plus simple:

détecter IE:

function detectIE() { 
    var ua = window.navigator.userAgent, 
    msie = ua.indexOf('MSIE '), 
    trident = ua.indexOf('Trident/'), 
    edge = ua.indexOf('Edge/'); 
    if (msie > 0) {return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);} 
    if (trident > 0) {var rv = ua.indexOf('rv:');return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);} 
    if (edge > 0) {return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);} 
    return false; 
} 

Différencier XMLHTTP et XDomain:

var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%27pune%2Cmh%27)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithke" 
if (window.XDomainRequest && detectIE()) { 
    var xdr = new XDomainRequest(); 
    xdr.open("GET", url, false); 
    xdr.onload = function() { 
     var res = JSON.parse(xdr.responseText); 
     if (res == null || typeof (res) == 'undefined') 
     { 
     res = JSON.parse(data.firstChild.textContent); 
     } 
     publishData(res); 
    }; 
    xdr.send(); 
} else { 
    var xmlhttp = new XMLHttpRequest(); 
    xmlhttp.onreadystatechange = function() { 
    if (xmlhttp.readyState == 4) { 
    if (xmlhttp.status == 200 || xmlhttp.status == 304) { 
     publishData(JSON.parse(xmlhttp.responseText)); 
    } else { 
     setTimeout(function(){ console.log("Request failed!") }, 0); 
    } 
    } 
} 
    xmlhttp.open("GET", url, true); 
    xmlhttp.send(); 
} 

function publishData(data){ 
    console.log(data); //Response 
} 

Exemple complet se trouve here

Questions connexes