2010-03-31 26 views
33

¿Cuál es la forma más fácil y segura de recuperar el objeto XmlHttpRequest que funciona en todos los navegadores? Sin ninguna biblioteca extra ¿Hay algún fragmento de código que uses a menudo?La manera más fácil de recuperar XmlHttpRequest entre navegadores

P.S. Sé que hay muchos ejemplos en la red, pero esta es precisamente la razón por la que estoy preguntando: hay demasiados ejemplos diferentes, y solo quiero que algo simple y probado funcione.

jQuery y otras bibliotecas NO es una opción. Why does jquery leak memory so badly?

+1

Sé que dices "sin usar bibliotecas externas" pero la respuesta es * todavía * "use jQuery". Tiene menos de 25k gzip. – cletus

+0

jQuery se usa porque es simple y fácil –

+1

Otra gran biblioteca es prototipo. Sin embargo, ¿podría explicar por qué no quiere usar una biblioteca? Podrían hacer tu vida mucho más fácil. –

Respuesta

59

Mientras yo recomendaría el uso de una biblioteca completa para hacer un uso más fácil, haciendo peticiones AJAX puede ser bastante simple en los navegadores modernos:

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(); 

El siguiente fragmento es un fragmento más avanzada basada en un fragmento de quirksmode.org e incluso soporta los navegadores muy viejos (mayores de Internet Explorer 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

Ya estamos usando jQuery, sin embargo, pierde memoria, lo cual es crucial en nuestro caso. Gracias por el fragmento, lo probaré. –

+0

¿Qué navegador usa Msxml3? No lo he visto antes –

+0

Cualquier sistema que no tenga disponible Msxml6 (que llamará Microsoft.XMLHTTP). Sé que al menos Windows 2000 SP4 tiene Msxml3 disponible :) – Wolph

4

no es 100% seguro de su pregunta - pero si usted está pidiendo la función para volver convertir una instancia del navegador Xmlhttp cruz - hemos utilizado este en nuestra biblioteca ajax nativa durante años - y nunca un problema en cualquier navegador

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

Conforme a lo solicitado, simple y demostrado que funciona:

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; 
} 

que se derrumba en una sola línea, obtenemos:

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

Según el IE Dev Center, y cito textualmente, "Para admitir versiones de IE anteriores a IE7, puede usar:" return new ActiveXObject (" MSXML2.XMLHTTP.3.0 ") – andreszs

+0

@Andrew, Sí, el enlace está aquí: https://msdn.microsoft.com/en-us/library/ms535874(v=vs.85).aspx#code-snippet-4. Los navegadores antiguos son realmente dolores de cabeza, aunque en estos días para proyectos personales lo más probable es que simplemente haga 'nueva XMLHttpRequest();'. – Pacerier

1

una manera más sencilla:

Detectar 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; 
} 

Diferenciar xmlhttp y 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 
} 

Ejemplo completo se puede encontrar here

Cuestiones relacionadas