2010-03-31 14 views
33

Jaki jest najłatwiejszy i najbezpieczniejszy sposób na odzyskanie obiektu XmlHttpRequest, który działa we wszystkich przeglądarkach? Bez żadnych dodatkowych bibliotek. Czy istnieje fragment kodu, którego często używasz?Najprostszym sposobem na odzyskanie między przeglądarkami XmlHttpRequest

P.S. Wiem, że w Internecie jest mnóstwo przykładów, ale właśnie dlatego proszę: jest zbyt wiele różnych przykładów i chcę po prostu czegoś prostego i sprawdzonego w działaniu.

jQuery i inne biblioteki NIE są opcją. Why does jquery leak memory so badly?

+1

wiem mówisz "bez korzystania z zewnętrznych bibliotek", ale odpowiedź to * nadal * "użyj jQuery". Jest pod spodem 25k gzip. – cletus

+0

jQuery jest używany, ponieważ jest prosty i łatwy. –

+1

Kolejna wspaniała biblioteka jest prototypowa. Czy możesz jednak wyjaśnić, dlaczego nie chcesz korzystać z biblioteki? Mogliby znacznie ułatwić sobie życie. –

Odpowiedz

59

A ja polecam używając pełnej biblioteki, aby korzystanie z łatwiejsze, dzięki czemu żądań AJAX może być dość prosty w nowoczesnych przeglądarek:

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

Poniższy fragment jest bardziej zaawansowany fragment oparty na fragmencie z quirksmode.org i obsługuje nawet bardzo starych przeglądarek (starszych niż 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

Korzystamy już z jQuery, jednak przecieka pamięć, co jest w naszym przypadku kluczowe. Dzięki za opis, wypróbuję to. –

+0

Która przeglądarka używa Msxml3? Nie widziałem tego wcześniej. –

+0

Dowolny system, który nie ma dostępnego Msxml6 (które wywoła Microsoft.XMLHTTP). Wiem, że co najmniej Windows 2000 SP4 ma Msxml3 dostępny :) – Wolph

4

nie 100% pewne Twoje pytanie - ale jeśli pytasz o funkcję ponownego skręcić przekrój instancji XMLHTTP przeglądarka - użyliśmy tego w naszej rodzimej biblioteki AJAX dla lat - i nigdy nie było problemu w dowolnej przeglądarce

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

wniosek, proste i sprawdzone do pracy:

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 go w jednej linii, otrzymujemy:

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

Zgodnie z IE Dev Center, i cytuję: "Aby obsługiwać wersje IE starsze niż IE7, można użyć:" return new ActiveXObject (" MSXML2.XMLHTTP.3.0 ") – andreszs

+0

@Andrew, tak, link jest tutaj: https://msdn.microsoft.com/en-us/library/ms535874(v=vs.85).aspx#code-snippet-4. Stare przeglądarki to naprawdę bóle głowy, choć obecnie w przypadku projektów osobistych najprawdopodobniej po prostu wykonam polecenie 'new XMLHttpRequest();'. – Pacerier

1

prostszy sposób:

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

różnicować XMLHTTP i 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 
} 

Pełna Przykład można znaleźć here

Powiązane problemy