jQuery .find () не возвращает данные в IE, а в Firefox и Chrome - PullRequest
24 голосов
/ 18 февраля 2009

Я выручил друга, выполнив для него небольшую веб-работу. Часть того, что ему было нужно, - это простой способ изменить пару фрагментов текста на своем сайте. Вместо того, чтобы он редактировал 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. Так что получается, что он всегда работает при запуске через веб-сервер разработки. Теперь я думаю, что IE просто не нравится делать .find в XML, загруженном с моего локального диска, поэтому, возможно, когда он находится на реальном веб-сервере, он будет работать нормально.

Я подтвердил, что он работает нормально при просмотре с веб-сервера. Должно быть особенность IE. Я предполагаю, что это потому, что веб-сервер устанавливает тип mime для передачи файла данных xml, и без этого IE не может правильно проанализировать xml.

Ответы [ 15 ]

19 голосов
/ 10 января 2010

Поскольку проблема IE заключается в том, что его синтаксический анализатор XML блокирует файлы XML, которые не передаются с использованием правильного заголовка "text / xml", вы можете включить немного кода в событие Ajax complete :

    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 <a href="http://www.w3schools.com/Xml/xml_parser.asp" rel="nofollow noreferrer">w3schools</a> method.
        // <a href="https://stackoverflow.com/questions/1919582/javascript-which-should-i-use-microsoft-xmlhttp-or-msxml2-xmlhttp">see also</a>
        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
    // <a href="http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest-origin" rel="nofollow noreferrer">origin type problems</a>

    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 <a href="http://www.w3schools.com/Xml/xml_parser.asp" rel="nofollow noreferrer">w3schools</a> method.
        // <a href="https://stackoverflow.com/questions/1919582/javascript-which-should-i-use-microsoft-xmlhttp-or-msxml2-xmlhttp">see also</a>
        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">

  

содержимое 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>

Это расширяет этот пример .

12 голосов
/ 18 февраля 2009

Проверьте тип содержимого ответа. Если вы получите 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 не поддерживает его.

6 голосов
/ 30 мая 2010

dataType: "xml" не решает эту проблему в IE8, скорее, он проходит через исключение "TypeError".

Быстрое и грязное исправление - это завершение xml-ответа в элемент html, например, div:

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

(работает во всех браузерах)

5 голосов
/ 19 февраля 2009

Вы можете обнаружить, что если вы передадите тип данных в ваш вызов 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>

EDIT:

На самом деле я только что испытал .find (), не работающий над проектом в любом браузере, но вместо этого я смог использовать .filter (). Раздражает, что мне пришлось прибегнуть к этому, но если это сработает ....

$(d).filter('message').each(......);
3 голосов
/ 12 января 2011

У меня также была такая же проблема, но я исправил проблему 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;
}
3 голосов
/ 17 июня 2010

Вы можете сделать

<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

1 голос
/ 07 декабря 2010

У меня также была такая же проблема при импорте контактов электронной почты. Мне удалось импортировать контакты и отображать их во всех браузерах, кроме IE, так как .find() не работал.

Итак, я назначил "text/xml" на response.contentType.

т.е. response.contentType = "text/xml" и это сработало.

ранее это было "text/html"

1 голос
/ 30 мая 2010
$.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, какой dataType он получает, чтобы он использовал правильные методы для обработки вашего запроса.

1 голос
/ 29 апреля 2010

Изменить следующий контент.

dataType :"text/xml",

до

dataType :"xml",

Нет необходимости изменять поиск ().

1 голос
/ 21 января 2010

Я столкнулся с той же проблемой, когда извлекал данные из XML-документа. После долгих поисков в интернете я нашел этот сайт, но не нашел правильного ответа на этот вопрос. Но один ответ помог мне решить проблему:

"Поскольку проблема IE заключается в том, что xml-парсер блокирует xml-файлы, которые не передаются с использованием правильного заголовка" text / xml ", вы можете включить немного кода в событие завершения Ajax:"

Я обнаружил две проблемы с IE при выполнении вызовов $ .ajax (...) и $ .get (...):

  1. Значение параметра xml должно быть в верхнем регистре («XML», а не «xml») для обоих вызовов - $ .ajax (..., dataType: «XML») и $. Get (xmlDataFilePath, function (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...