代码之家  ›  专栏  ›  技术社区  ›  Steve Hiner

jquery.find()不返回IE中的数据,但在firefox和chrome中返回。

  •  24
  • Steve Hiner  · 技术社区  · 16 年前

    我帮一个朋友做了点网络工作。他需要的部分是一个简单的方法来改变他的网站上的几段文字。我没有让他编辑HTML,而是决定提供一个包含其中消息的XML文件,我使用jquery将它们从文件中拉出并插入到页面中。

    它很管用…在火狐和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中查找,这样当它在实际的Web服务器上运行时,它就可以正常工作了。

    我已经确认,当从Web服务器浏览时,它可以正常工作。IE一定是个特例。我猜这是因为Web服务器为XML数据文件传输设置了mime类型,如果没有它,IE就无法正确解析XML。

    15 回复  |  直到 9 年前
        1
  •  12
  •   Matthew Crumley    16 年前

    检查响应的内容类型。如果将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
  •  19
  •   Community CDub    8 年前

    由于IE的问题在于它的XML解析器阻塞了未使用正确的“text/xml”头传递的XML文件,因此可以在 AJAX完成 事件:

        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>
    
    

    .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 .

        3
  •  6
  •   McMadsen    15 年前

    数据类型:“xml”并不能在IE8中解决这个问题,而是通过“typeerror”预期来解决。

    快速修复是将XML响应包装在HTML元素中,如DIV:

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

    (适用于所有浏览器)

        4
  •  5
  •   MJJames    16 年前

    您可能会发现,如果将数据类型传递到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(......);
    
        5
  •  3
  •   sanjeev    14 年前

    我也有同样的问题,但是我用下面的代码修复了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
  •  3
  •   Jason Higgins    12 年前

    你可以做到

    <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。

        7
  •  1
  •   jacobangel    16 年前

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

        8
  •  1
  •   Bigabdoul    15 年前

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

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

    在进行$.Ajax(…)和$.get(…)调用时,我发现了IE的两个问题:

    1. 这个 XML 两个调用的参数值都必须为大写(“xml”而不是“xml”)-.Ajax(…,数据类型:“xml”)和 $.get(xmldatafilepath,函数(d)…,“xml”)

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

    第二个问题是这样解决的:

    $(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
    
        9
  •  1
  •   RobertPitt    15 年前
    $.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
  •   Alfred redcoder    12 年前

    更改以下内容。

    dataType :"text/xml",
    

    dataType :"xml",
    

    无需更改find()。

        11
  •  1
  •   Alfred redcoder    12 年前

    导入电子邮件联系人时,我也遇到了同样的问题。我可以导入联系人并在除IE外的所有浏览器中显示 .find() 不工作。

    所以,我指派 "text/xml" response.contentType .

    response.contentType = "text/xml" 它奏效了。

    早些时候 "text/html"

        12
  •  0
  •   prof. Xavier    15 年前

    我也遇到了同样的问题,我正在开发一个基于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... 
       }
     });
    
        13
  •  0
  •   stevensf    15 年前

    我也有同样的问题…

    解决方法如下:

    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对象…

        14
  •  0
  •   TessellatingHeckler    10 年前

    它工作得很好!!!!试试这个,

    铬/火狐:

    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; 
    
    }
    
        15
  •  0
  •   christophe    9 年前

    如果XML是由PHP脚本生成的,那么可以

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

    那么find方法在每个浏览器上都有效