【问题标题】:AJAX responseXML errorsAJAX responseXML 错误
【发布时间】:2010-11-04 01:21:16
【问题描述】:

在发出 AJAX 请求和处理响应时,我遇到了一些奇怪的问题。

我正在对 xml 文件进行 ajax 调用。但是,当我得到响应时,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,所以可能有些东西我看不正确。 我一直在疯狂寻找任何关于为什么或如何解决它的迹象,但没有运气。 任何想法都会很棒。

编辑:

我知道有一个框架会更好,但是老板不想为一个 ajax 功能添加一个框架('just' 对于 ajax 来说不是一个公平的词:P)。所以我用纯javascript来做。

XML 文件格式正确,我可以在 Web 浏览器中很好地看到它,但为了完成,这是我正在使用的测试文件:

<?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,因为他是最接近的工作提示。

【问题讨论】:

    标签: javascript ajax cross-browser


    【解决方案1】:

    Aron 在https://stackoverflow.com/a/2081466/657416 中提供的答案在我看来是最简单(也是最好)的答案。这是我的工作代码:

    ajax = ajaxRequest();
    ajax.overrideMimeType("text/xml");
    ajax.open("GET", myurl;
    

    【讨论】:

      【解决方案2】:

      此问题主要发生在浏览器错误检测到内容类型或未正确发送时。

      覆盖它更容易:

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

      不知道为什么...这个问题只发生在 Safari 和 Chrome(WebKit 浏览器,服务器正确发送标头)。

      【讨论】:

        【解决方案3】:

        我相信您的网络服务器需要使用“ConferenceRoomSchedules.xml”提供正确的响应标头,例如Content-Type:text/xml 或任何其他 xml 类型。

        【讨论】:

          【解决方案4】:

          几年前我也遇到过同样的问题,然后我放弃了 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;
          }
          

          当然,这是非常古老的代码,但它仍然适用于我几年前建立的网站。我同意其他人的观点,尽管我现在通常使用框架,所以我不必再使用这个代码或类似的东西了。

          您可以在 Request onreadystate 函数中忽略拆分等的一些细节。如果请求的长度超过一定长度,它应该将请求转换为帖子,但我只是决定做一个帖子总是更好。

          【讨论】:

          • responseText 在跨浏览器环境中看起来很稳定,我想我会使用这种方法。感谢脚本
          • 没问题,很高兴我能帮上忙!
          • 您的回答为 7 年后的类似问题指明了正确的方向 :) 我在 IE9 中使用 .response 并且在所有其他浏览器中都不起作用。 .responseText 适用于所有浏览器。好!
          【解决方案5】:

          我可以建议您查看为您隐藏和管理这些跨浏览器问题的框架(以可靠的方式)。这里的一个好点是jQuery。自己做这些事情会变得非常困难和复杂。

          This 可能是你需要的。

          //编辑: 这就是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!");
            }
          }
          

          【讨论】:

          • 这是个好建议。让库担心跨浏览器问题。
          • 我同意,我使用过 jQuery,但如果我们只使用 ajax,我的老板不想用整个框架填充网站。所以我必须自己做。尽管我仍在试图说服他使用框架。
          • @Tony L.,告诉他 jQuery 是一个脚本,而不是一个框架。框架听起来很沉重。
          • @Tony:然后告诉他,通过自己编写,您需要大约 5 天的开发时间 + 可能由于一些奇怪的浏览器怪癖而修复错误,而使用 jQuery,您可以免费获得一切更安全。在这里看看这个:code.google.com/apis/ajaxlibs
          【解决方案6】:

          您是在调用相对于当前文档的 URL 吗?由于 IE 将使用 ActiveXObject,它可能需要一个绝对路径,例如:

          http://some.url/ConferenceRoomSchedules.xml

          至于 XML,您确定它的格式正确吗?例如,它会在 XML 编辑器中加载吗?

          【讨论】:

          • 感谢您的回复。我尝试使用绝对路径但仍然没有运气,在 IE 中的结果相同。
          【解决方案7】:

          为避免您的跨浏览器问题(并节省您自己编写大量强大社区已经开发、测试和审查的项目),您应该选择一个 javascript 库。 JQuery 和 Dojo 是不错的选择。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-06-17
            • 1970-01-01
            • 2013-08-08
            • 1970-01-01
            • 1970-01-01
            • 2011-10-21
            • 2011-03-11
            相关资源
            最近更新 更多