jQuery .find()不会在IE中返回数据,但会在Firefox和Chrome中返回

时间:2009-02-18 18:28:18

标签: javascript jquery xml

通过为他做一些网络工作,我帮助了一位朋友。他需要的部分内容是在他的网站上更改几段文字的简单方法。我没有让他编辑HTML,而是决定提供一个带有消息的XML文件,我使用jQuery将它们从文件中拉出来并将它们插入到页面中。

效果很好......在Firefox和Chrome中,在IE7中效果不是很好。我希望你们中的一个能告诉我原因。我做了一个公平但谷歌搜索但找不到我想要的东西。

这是XML:

<?xml version="1.0" encoding="utf-8" ?>
<messages>
  <message type="HeaderMessage">
    This message is put up in the header area.
  </message>
  <message type="FooterMessage">
    This message is put in the lower left cell.
  </message>
</messages>

这是我的jQuery调用:

<script type="text/javascript">
  $(document).ready(function() {
    $.get('messages.xml', function(d) {
      //I have confirmed that it gets to here in IE
      //and it has the xml loaded.
      //alert(d); gives me a message box with the xml text in it
      //alert($(d).find('message')); gives me "[object Object]"
      //alert($(d).find('message')[0]); gives me "undefined"
      //alert($(d).find('message').Length); gives me "undefined"
      $(d).find('message').each(function() {
        //But it never gets to here in IE
        var $msg = $(this);
        var type = $msg.attr("type");
        var message = $msg.text();
        switch (type) {
        case "HeaderMessage":
          $("#HeaderMessageDiv").html(message);
          break;
        case "FooterMessage":
          $("#footermessagecell").html(message);
          break;
          default:
        }
      });
    });
  });
</script>

在IE中我是否需要做些不同的事情?基于带有[object Object]的消息框,我假设.find正在IE中工作但由于我无法使用[0]索引到数组或检查它的长度我猜这意味着.find不是返回任何结果。有什么理由可以在Firefox和Chrome中完美运行但在IE中失败?

我是jQuery的新手,所以我希望我没有做过愚蠢的事。上面的代码被从论坛中删除,并根据我的需要进行了修改。由于jQuery是跨平台的,我认为我不必处理这个混乱。

编辑:我发现如果我在Visual Studio 2008中加载页面并运行它,那么它将在IE中运行。事实证明,它在运行开发Web服务器时始终有效。现在我想IE只是不喜欢在我的本地驱动器上加载的XML中执行.find所以当它在实际的Web服务器上时它可以正常工作。

我已经确认从Web服务器浏览时工作正常。必须是IE的特色。我猜这是因为Web服务器为xml数据文件传输设置了mime类型,而且IE没有正确解析xml。

15 个答案:

答案 0 :(得分:19)

由于IE的问题是它的xml解析器在使用正确的“text / xml”标头传递的xml文件上没有阻塞,你可以在 Ajax完整事件中包含一些代码:< / p>

    complete: function( xhr, status )
    {
      alert( "COMPLETE.  You got:\n\n" + xhr.responseText ) ;
      if( status == 'parsererror' )
      {
        alert( "There was a PARSERERROR.  Luckily, we know how to fix that.\n\n" +
               "The complete server response text was " + xhr.responseText ) ;

        xmlDoc = null;

        // Create the xml document from the responseText string.
        // This uses the w3schools method.
        // see also
        if( window.DOMParser )
        {
          parser=new DOMParser();
          xmlDoc=parser.parseFromString( xhr.responseText,"text/xml" ) ;
        }
        else // Internet Explorer
        {
          xmlDoc=new ActiveXObject( "Microsoft.XMLDOM" ) ;
          xmlDoc.async = "false" ;
          xmlDoc.loadXML( xhr.responseText ) ;
        }

        $( '#response' ).append( '<p>complete event/xmlDoc: ' + xmlDoc + '</p>' ) ;
        $( '#response' ).append( '<p>complete event/status: ' + status + '</p>' ) ;

        processXMLDoc( xmlDoc ) ;
      }
    },

这是一个更完整的例子

<!DOCTYPE html>
<html>
<head>
<title>Reading XML with jQuery</title>
<style>
#response
{
  border: solid 1px black;
  padding: 5px;
}
</style>
<script src="jquery-1.3.2.min.js"></script>
<script>
function processXMLDoc( xmlDoc )
{
  var heading = $(xmlDoc).find('heading').text() ;
  $( '#response' ).append( '<h1>' + heading + '</h1>' ) ;

  var bodyText = $(xmlDoc).find('body').text() ;
  $( '#response' ).append( '<p>' + bodyText + '</p>' ) ;
}
$(document).ready(function()
{
  jQuery.ajax({

    type: "GET",

    url: "a.xml",  // ! watch out for same
    // origin type problems

    dataType: "xml", // 'xml' passes it through the browser's xml parser

    success: function( xmlDoc, status )
    {
      // The SUCCESS EVENT means that the xml document
      // came down from the server AND got parsed successfully
      // using the browser's own xml parsing caps.

      processXMLDoc( xmlDoc );

      // IE gets very upset when
      // the mime-type of the document that
      // gets passed down isn't text/xml.

      // If you are missing the text/xml header
      // apparently the xml parse fails,
      // and in IE you don't get to execute this function AT ALL.

    },
    complete: function( xhr, status )
    {
      alert( "COMPLETE.  You got:\n\n" + xhr.responseText ) ;
      if( status == 'parsererror' )
      {
        alert( "There was a PARSERERROR.  Luckily, we know how to fix that.\n\n" +
               "The complete server response text was " + xhr.responseText ) ;

        xmlDoc = null;

        // Create the xml document from the responseText string.
        // This uses the w3schools method.
        // see also
        if( window.DOMParser )
        {
          parser=new DOMParser();
          xmlDoc=parser.parseFromString( xhr.responseText,"text/xml" ) ;
        }
        else // Internet Explorer
        {
          xmlDoc=new ActiveXObject( "Microsoft.XMLDOM" ) ;
          xmlDoc.async = "false" ;
          xmlDoc.loadXML( xhr.responseText ) ;
        }

        $( '#response' ).append( '<p>complete event/xmlDoc: ' + xmlDoc + '</p>' ) ;
        $( '#response' ).append( '<p>complete event/status: ' + status + '</p>' ) ;

        processXMLDoc( xmlDoc ) ;
      }
    },
    error: function( xhr, status, error )
    {
      alert( 'ERROR: ' + status ) ;
      alert( xhr.responseText ) ;
    }
  });
});
</script>
</head>
<body>
  <div>
    <h1><a href="http://think2loud.com/reading-xml-with-jquery/">Reading XML with jQuery</a></h1>
    <p>
      <a href="http://docs.jquery.com/Ajax/jQuery.ajax#options">#1 jQuery.ajax ref</a>
    </p>

  </div>

  <p>Server says:</p>
  <pre id="response">

  </pre>
</body>
</html>

a.xml的内容

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

它扩展了this example

答案 1 :(得分:12)

检查响应的内容类型。如果将messages.xml作为错误的mime类型,Internet Explorer将不会将其解析为XML。

要检查内容类型,您需要访问XMLHttpRequest对象。正常成功回调不会将其作为参数传递,因此您需要添加通用ajaxComplete或ajaxSuccess事件处理程序。这些事件的第二个参数是XMLHttpRequest对象。您可以在其上调用getResponseHeader方法来获取内容类型。

$(document).ajaxComplete(function(e, x) {
    alert(x.getResponseHeader("Content-Type"));
});

不幸的是,我在Internet Explorer中无法覆盖服务器发送的内容,因此如果错误则需要更改服务器以发送内容类型的“text / xml”。

某些浏览器有一个overrideMimeType方法,您可以在send之前调用它以强制它使用“text / xml”,但据我所知,Internet Explorer不支持这种方法。

答案 2 :(得分:6)

dataType:“xml”不能解决IE8中的这个问题,而是通过“TypeError”预测来解决这个问题。

快速&amp;脏修复,是将xml响应包装在html元素中,如div:

$("<div>" + xml + "</div>").find("something");

(适用于所有浏览器)

答案 3 :(得分:5)

您可能会发现,如果将数据类型传递给get调用,它可能会正确解析为XML。 IE的怪癖可能会阻止jQuery将其自动检测为XML,从而导致错误的数据类型被传递给回调函数。

<script type="text/javascript">
      $(document).ready(function() {
        $.get('messages.xml', function(d) {
          //I have confirmed that it gets to here in IE
          //and it has the xml loaded.
          //alert(d); gives me a message box with the xml text in it
          //alert($(d).find('message')); gives me "[object Object]"
          //alert($(d).find('message')[0]); gives me "undefined"
          //alert($(d).find('message').Length); gives me "undefined"
          $(d).find('message').each(function() {
            //But it never gets to here in IE
            var $msg = $(this);
            var type = $msg.attr("type");
            var message = $msg.text();
            switch (type) {
            case "HeaderMessage":
              $("#HeaderMessageDiv").html(message);
              break;
            case "FooterMessage":
              $("#footermessagecell").html(message);
              break;
              default:
            }
          });
        }, "xml");
      });
</script>

编辑:

我实际上只是经历过.find()不能在任何浏览器中为项目工作,但我能够使用.filter()代替。令人讨厌的是我不得不诉诸于此,但如果它有效......

$(d).filter('message').each(......);

答案 4 :(得分:3)

你可以做到

<a>
<messages>
  <message type="HeaderMessage">
    This message is put up in the header area.
  </message>
  <message type="FooterMessage">
    This message is put in the lower left cell.
  </message>
</messages>
</a>

并使用find()。它适用于IE8和firefox v.3.6.3

答案 5 :(得分:3)

我也有同样的问题,但我使用下面的代码修复了IE jQuery XML .find()问题。

注意:使用.text()代替.html()。

jQuery.ajax({
 type: "GET",
        url: "textxml.php",
        success: function(msg){             
            data = parseXml(msg);
            //alert(data);
            var final_price = jQuery(data).find("price1").text();
            alert(final_price); 
            }
    });     

function parseXml(xml) {
     if (jQuery.browser.msie) {
        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
        xmlDoc.loadXML(xml);
        xml = xmlDoc;
    }   
    return xml;
}

答案 6 :(得分:1)

有时IE会将换行符作为额外节点读取。尝试删除标签上的额外空白区域,或尝试将其封装为CDATA。

答案 7 :(得分:1)

当我从XML文档中检索数据时遇到了同样的问题。在互联网上搜索了很多内容后,我找到了这个网站,但没有正确的答案。但是有一个答案帮助我解决了这个问题:

“由于IE的问题是它的xml解析器在使用正确的”text / xml“标头传递的xml文件上没有阻塞,你可以在Ajax完成事件中包含一些代码:”

在制作$ .ajax(...)和$ .get(...)调用时,我发现了IE的两个问题:

  1. 对于两个调用, xml 参数值必须为大写('XML'而不是'xml') - $ .ajax(...,dataType:“XML”)和 $。get(xmlDataFilePath,function(d){...},“xml”)

  2. 当ajax调用成功时,回调函数的xml参数实际上是字符串而不是XML DOM对象

  3. 第二个问题以这种方式解决:

    $(document).ready(function()
    {
        $.ajax(
        { 
            type: "GET",
            url: "messages.xml", 
            dataType: "XML", /* this parameter MUST BE UPPER CASE for it to work in IE */
            success: function(xml)
            { 
                processXmlDoc( createXmlDOMObject ( xml ) );
            }, /* success: */
            error: function(xhr, textStatus, errorThrown)
            { 
                alert(textStatus + ' ' + errorThrown);
            } /* error: */
        });/* $.ajax */
    
        function createXmlDOMObject(xmlString)
        {
            var xmlDoc = null;
    
            if( ! window.DOMParser )
            {
                // the xml string cannot be directly manipulated by browsers 
                // such as Internet Explorer because they rely on an external 
                // DOM parsing framework...
                // create and load an XML document object through the DOM 
                // ActiveXObject that it can deal with
                xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" );
                xmlDoc.async = false;
                xmlDoc.loadXML( xmlString );
            }
            else
            {
                // the current browser is capable of creating its own DOM parser
                parser = new DOMParser();
                xmlDoc = parser.parseFromString( xmlString, "text/xml" ) ;
            }
    
            return xmlDoc;
        }
    
        function processXmlDoc(xmlDoc)
        {
            // write here your XML processing logic for the document object...
        } 
    }); // $(document).ready
    

答案 8 :(得分:1)

更改以下内容。

dataType :"text/xml",

dataType :"xml",

无需更改find​​()。

答案 9 :(得分:1)

$.ajax({
  url: 'messages.xml',
  success: function(data){
     $(d).find('message').each(function(){
        //But it never gets to here in IE
        var $msg = $(this);
        var type = $msg.attr("type");
        var message = $msg.text();
        switch (type) {
          case "HeaderMessage":
             $("#HeaderMessageDiv").html(message);
          break;
          case "FooterMessage":
             $("#footermessagecell").html(message);
          break;
        }
      });
  },
  dataType: 'xml'
});

尝试告诉jQuery它获取的数据类型,以便它使用正确的方法来处理您的请求。

答案 10 :(得分:1)

导入电子邮件联系人时也遇到了同样的问题。我能够在IE中导入联系人并在所有浏览器中显示,因为.find()无效。

所以,我已将"text/xml"分配给response.contentType

即。 response.contentType = "text/xml"它有效。

之前它是"text/html"

答案 11 :(得分:0)

我遇到了同样的问题,我正在开发一个基于Web的应用程序,但是我需要它在CD中离线部署它。我在此页面中找到了解决方案,该解决方案与http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests上方的解决方案相同 代码很简单:

 $.ajax({
   url: "data.xml",
   dataType: ($.browser.msie) ? "text" : "xml",
   success: function(data){
     var xml;
     if (typeof data == "string") {
       xml = new ActiveXObject("Microsoft.XMLDOM");
       xml.async = false;
       xml.loadXML(data);
     } else {
       xml = data;
     }
     // write here your XML processing logic for the document object... 
   }
 });

答案 12 :(得分:0)

我有同样的问题......

解决了这个问题:

http://www.w3schools.com/dom/dom_parser.asp

if (window.DOMParser)
  {
  parser=new DOMParser();
  xmlDoc=parser.parseFromString(text,"text/xml");
  }
else // Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async="false";
  xmlDoc.loadXML(text); 
  }

使用它将var转换为xml对象...

答案 13 :(得分:0)

它工作正常!!!试试这个,

铬/火狐:

xml.children[0].childNodes[1].innerHTML;

IE8 + / Safari浏览器:

xml.childNodes[0].childNodes[1].textContent;

IE8:

xml.documentElement.childNodes[1].text;

示例代码,

var xml = $.parseXML(XMLDOC); 

Var xmlNodeValue = ""; 

if(userAgent.match("msie 8.0")){

xmlNodeValue = xml.children[0].childNodes[1].innerHTML;

}else{ // IE8+

xmlNodeValue = xml.childNodes[0].childNodes[1].textContent; 

}

答案 14 :(得分:0)

如果XML是由PHP脚本生成的,则可以执行

<?php
    header("Content-type: text/xml");
    echo '<myxml></myxml>';
?>

然后find方法适用于每个浏览器