AJAX responseXML ошибки - PullRequest
       11

AJAX responseXML ошибки

3 голосов
/ 18 июня 2009

У меня были некоторые странные проблемы, когда речь шла о выполнении AJAX-запроса и обработке ответа.

Я делаю вызов ajax для файла xml. Однако, когда я получаю ответ, свойство xhr.responseText прекрасно работает в Firefox, но не в IE. Другое дело, что я пытаюсь получить доступ к xhr.responseXML как XMLDocument, но он говорит мне, что в firefox он сообщает, что xhr.responseXML не определен, то есть он даже не показывает мне неопределенную ошибку или отображает вывод.

Это код, который я использую для запроса:

var ajaxReq = function(url, callback) {
    //initialize the xhr object and settings
    var xhr = window.ActiveXObject ?
            new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(),
    //set the successful connection function
        httpSuccess = function(xhr) {
            try {
                // IE error sometimes returns 1223 when it should be 204
                //  so treat it as success, see XMLHTTPRequest #1450
                // this code is taken from the jQuery library with some modification.
                return !xhr.status && xhr.status == 0 ||
                        (xhr.status >= 200 && xhr.status < 300) ||
                        xhr.status == 304 || xhr.status == 1223;
            } catch (e) { }
            return false;
        };

    //making sure the request is created
    if (!xhr) {
        return 404; // Not Found
    }


    //setting the function that is going to be called after the request is made
    xhr.onreadystatechange = function() {
        if (!httpSuccess(xhr)) {
            return 503; //Service Unavailable
        }
        if (xhr.responseXML != null && xhr.responseText != null &&
                xhr.responseXML != undefined && xhr.responseText != undefined) {
            callback(xhr);
        }
    };


    //open request call
    xhr.open('GET', url, true);

    //setup the headers
    try {
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.setRequestHeader("Accept", "text/xml, application/xml, text/plain");
    } catch ( ex ) {
        window.alert('error' + ex.toString());
    }

    //send the request
    try {
        xhr.send('');
    } catch (e) {
        return 400; //bad request
    }

    return xhr;
};

и вот как я вызываю функцию для проверки результатов:

window.onload = function() {
    ajaxReq('ConferenceRoomSchedules.xml', function(xhr) {
        //in firefox this line works fine,
        //but in ie it doesnt not even showing an error
        window.document.getElementById('schedule').innerHTML = xhr.responseText;
        //firefox says ''xhr.responseXML is undefined'.
        //and ie doesn't even show error or even alerts it.
        window.alert(xhr.reponseXML.documentElement.nodeName);
    });
}

Это также моя первая попытка работать с AJAX, так что может быть что-то, на что я не обращаю внимания. Я безумно искал признаки того, почему или как это исправить, но не повезло. любые идеи были бы великолепны.

EDIT:

Я знаю, что это было бы лучше с фреймворком, но босс не хочет добавлять фреймворк только для функциональности ajax («просто» - нечестное слово для ajax: P). Так что я делаю это с чистым JavaScript.

XML-файл правильно сформирован, я хорошо вижу его в веб-браузере, но для завершения я использую тестовый файл:

<?xml version="1.0" encoding="utf-8"?>
<rooms>
  <room id="Blue_Room">
    <administrator>somebody@department</administrator>
    <schedule>
      <event>
        <requester>
          <name>Johnny Bravo</name>
          <email>jbravo@department</email>
        </requester>
        <date>2009/09/03</date>
        <start_time>11:00:00 GMT-0600</start_time>
        <end_time>12:00:00 GMT-0600</end_time>
      </event>
    </schedule>
  </room>
  <room id="Red_Room">
    <administrator>somebody@department</administrator>
    <schedule>
    </schedule>
  </room>
  <room id="Yellow_Room">
    <administrator>somebody@department</administrator>
    <schedule>
    </schedule>
  </room>
</rooms>

РЕДАКТИРОВАТЬ 2: Что ж, хорошие новости в том, что я убедил моего босса использовать jQuery, плохие новости в том, что AJAX все еще озадачивает меня. Я буду читать больше об этом просто для любопытства. Спасибо за подсказки, и я дал ответную оценку Heat Miser, потому что он был ближайшим рабочим советом.

Ответы [ 7 ]

4 голосов
/ 18 июня 2009

У меня была такая же проблема несколько лет назад, потом я отказался от responseXML и начал всегда использовать responseText. Эта функция синтаксического анализа всегда работала для меня:

function parseXml(xmlText){
    try{
        var text = xmlText;
        //text = replaceAll(text,"&lt;","<");
        //text = replaceAll(text,"&gt;",">");
        //text = replaceAll(text,"&quot;","\"");
        //alert(text);
        //var myWin = window.open('','win','resize=yes,scrollbars=yes');
        //myWin.document.getElementsByTagName('body')[0].innerHTML = text;
        if (typeof DOMParser != "undefined") { 
            // Mozilla, Firefox, and related browsers 
            var parser=new DOMParser();
            var doc=parser.parseFromString(text,"text/xml");
            //alert(text);
            return doc; 
        }else if (typeof ActiveXObject != "undefined") { 
            // Internet Explorer. 
        var doc = new ActiveXObject("Microsoft.XMLDOM");  // Create an empty document 
            doc.loadXML(text);            // Parse text into it 
            return doc;                   // Return it 
        }else{ 
            // As a last resort, try loading the document from a data: URL 
            // This is supposed to work in Safari. Thanks to Manos Batsis and 
            // his Sarissa library (sarissa.sourceforge.net) for this technique. 
            var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text); 
            var request = new XMLHttpRequest(); 
            request.open("GET", url, false); 
            request.send(null); 
            return request.responseXML; 
        }
    }catch(err){
        alert("There was a problem parsing the xml:\n" + err.message);
    }
}

С этим объектом XMLHttpRequest:

// The XMLHttpRequest class object

debug = false;

function Request (url,oFunction,type) {
    this.funct = "";
    // this.req = "";
    this.url = url;
    this.oFunction = oFunction;
    this.type = type;
    this.doXmlhttp = doXmlhttp;
    this.loadXMLDoc = loadXMLDoc;
}

function doXmlhttp() {
    //var funct = "";
    if (this.type == 'text') {
        this.funct = this.oFunction + '(req.responseText)';
    } else {
        this.funct = this.oFunction + '(req.responseXML)';
    }
    this.loadXMLDoc();
    return false;
}

function loadXMLDoc() {
    //alert(url);
    var functionA = this.funct;
    var req;
    req = false;

    function processReqChange() {
        // alert('reqChange is being called');
        // only if req shows "loaded"
        if (req.readyState == 4) {
            // only if "OK"
            if (req.status == 200) {
                // ...processing statements go here...
                eval(functionA);
                if(debug){
                    var debugWin = window.open('','aWindow','width=600,height=600,scrollbars=yes');
                    debugWin.document.body.innerHTML = req.responseText;
                }
            } else {
                alert("There was a problem retrieving the data:\n" +
                    req.statusText + '\nstatus: ' + req.status);
                if(debug){
                    var debugWin = window.open('','aWindow','width=600,height=600,scrollbars=yes');
                    debugWin.document.body.innerHTML = req.responseText;
                }
            }
            }
    }

    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
        try {
            req = new XMLHttpRequest();
        } catch(e) {
            req = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
        try {
                req = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
                try {
                    req = new ActiveXObject("Microsoft.XMLHTTP");
                } catch(e) {
                    req = false;
                }
        }
    }



    if(req) {
        req.onreadystatechange = processReqChange;
        if(this.url.length > 2000){
            var urlSpl = this.url.split('?');
            req.open("POST",urlSpl[0],true);
            req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            req.send(urlSpl[1]);
        } else {
            req.open("GET", this.url, true);
            req.send("");
        }
    }
}

function browserSniffer(){
    if(navigator.userAgent.toLowerCase().indexOf("msie") != -1){
        if(navigator.userAgent.toLowerCase().indexOf("6")){
            return 8;
        }else{
            return 1;
        }
    }
    if(navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
        return 2;
    }
    if(navigator.userAgent.toLowerCase().indexOf("opera") != -1){
        return 3;
    }
    if(navigator.userAgent.toLowerCase().indexOf("safari") != -1){
        return 4;
    }
    return 5;
}

Конечно, это очень старый код, но он все еще работает для меня на сайте, который я создал несколько лет назад. Я согласен со всеми, хотя в настоящее время я обычно использую фреймворк, поэтому мне больше не нужно использовать этот код или что-то подобное

Вы можете игнорировать некоторые детали с помощью split и т. Д. В функции Request onreadystate. Предполагалось, что запрос будет преобразован в сообщение, если оно длиннее определенной длины, но я просто решил, что сообщение всегда лучше делать.

3 голосов
/ 17 января 2010

Эта проблема возникает в основном, когда браузер неправильно определил тип контента или неправильно отправил.

Его проще просто переопределить:

var request = new XMLHttpRequest(); 
request.open("GET", url, false); 
request.overrideMimeType("text/xml");
request.send(null); 
return request.responseXML; 

Не знаю, почему ... Эта проблема возникает только в Safari и Chrome (браузеры WebKit, сервер правильно отправляет заголовки).

1 голос
/ 18 июня 2009

Вы называете URL относительно текущего документа? Поскольку IE будет использовать ActiveXObject, ему может понадобиться абсолютный путь, например:

http://some.url/ConferenceRoomSchedules.xml

Что касается XML, вы уверены, что он правильно сформирован? Например, загружается ли он в редактор XML?

1 голос
/ 18 июня 2009

Я могу предложить вам взглянуть на фреймворки, которые скрывают и управляют этими кросс-браузерными проблемами для вас (надежно) Хороший момент здесь - jQuery . Выполнение этих вещей самостоятельно может стать довольно трудным и сложным.

Это может быть то, что вам нужно.

// Изменить: Вот как w3school показывает это:

function ajaxFunction()
{
var xmlhttp;
if (window.XMLHttpRequest)
  {
  // code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else if (window.ActiveXObject)
  {
  // code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
else
  {
  alert("Your browser does not support XMLHTTP!");
  }
}
0 голосов
/ 25 января 2012

Ответ, предоставленный Ароном в https://stackoverflow.com/a/2081466/657416, с моей точки зрения, самый простой (и лучший). Вот мой рабочий код:

ajax = ajaxRequest();
ajax.overrideMimeType("text/xml");
ajax.open("GET", myurl;
0 голосов
/ 04 января 2010

Я считаю, что ваш веб-сервер должен обслуживать правильные заголовки ответа с помощью «ConferenceRoomSchedules.xml», например Content-Type: text / xml или любой другой тип xml.

0 голосов
/ 18 июня 2009

Чтобы избежать кросс-браузерных проблем (и сэкономить на кодировании множества элементов, которые уже разработано, протестировано и проверено сильным сообществом), вам следует выбрать библиотеку javascript. JQuery и Dojo - отличный выбор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...