javascript IE9 拒绝处理 XML 响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9746515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 07:41:40  来源:igfitidea点击:

IE9 refuses to process XML response

javascriptjqueryxmlajaxinternet-explorer-9

提问by Robert Smith

This is a question in relation to this one.

这是一个与相关的问题。

In UPDATE II, I added a script based on Jamie's feedback.

UPDATE II 中,我根据 Jamie 的反馈添加了一个脚本。

UPDATE - tl;dr:

更新 - tl;博士

I created a fiddle with a temporary key so you guys can see the problem more easily: http://jsfiddle.net/S6wEN/.

我创建了一个带有临时密钥的小提琴,以便你们可以更轻松地看到问题:http: //jsfiddle.net/S6wEN/

As this question was getting too long, this is a summary.

由于这个问题太长了,这是一个总结。

  • I tried to use imgur API to update an image via cross domain XHR.
  • In order to abstract details in the implementation, I'm using Jquery Form Plugin (obviously, it's contained in the fiddle).
  • Works great in Chrome, Firefox, etc but it doesn't work in IE9.
  • The expected result is to update the image and retrieve image type.
  • 我尝试使用 imgur API 通过跨域 XHR 更新图像。
  • 为了抽象实现中的细节,我使用了 Jquery 表单插件(显然,它包含在小提琴中)。
  • 在 Chrome、Firefox 等中运行良好,但在 IE9 中不起作用。
  • 预期的结果是更新图像并检索图像类型。

You can still find the details below.

您仍然可以在下面找到详细信息。

Thanks

谢谢



I have this HTML:

我有这个 HTML:

<body>
<form id="uploadForm" action="http://api.imgur.com/2/upload.xml" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="key" value="MYKEY">
    File: <input type="file" name="image">
    Return Type: <select id="uploadResponseType" name="mimetype">
        <option value="xml">xml</option>
    </select>
    <input type="submit" value="Submit 1" name="uploadSubmitter1">
</form>

<div id="uploadOutput"></div>
</body>

So basically, I have a form to upload an image to imgur via cross domain XHR. In order to manage the nasty details, I'm using Jquery Form Plugin, which works well. However, when I try to send an image to imgur and receive an xml response, it doesn't work as expected in IE9 (I haven't tested in IE8 but I don't expect great news). It works great in Chrome and Firefox. This is the javascript part:

所以基本上,我有一个表格可以通过跨域XHR将图像上传到imgur。为了管理讨厌的细节,我使用了Jquery Form Plugin,它运行良好。但是,当我尝试向 imgur 发送图像并接收 xml 响应时,它在 IE9 中无法正常工作(我没有在 IE8 中进行过测试,但我不希望有好消息)。它在 Chrome 和 Firefox 中运行良好。这是javascript部分:

(function() {
$('#uploadForm').ajaxForm({
        beforeSubmit: function(a,f,o) {
           o.dataType = $('#uploadResponseType')[0].value;
           $('#uploadOutput').html('Submitting...');
        },

        complete: function(data) {
        var xmlDoc = $.parseXML( data.responseText ),
            $xml = $( xmlDoc );
            $('#uploadOutput').html($xml.find('type'));

        }
    });
})();  

In IE9 I receive the following errors:

在 IE9 中,我收到以下错误:

SCRIPT5022: Invalid XML: null 
jquery.min.js, line 2 character 10890

XML5619: Incorrect document syntax. 
, line 1 character 1

I also used the example given in Jquery Form Plugin's page, which uses only Javascript but it doesn't help. Obviously, the first error referring to Jquery disappears but I can't obtain the expected results (in this case, image/jpegin the div with id="uploadOutput").

我还使用了 Jquery Form Plugin's page 中给出的例子,它只使用了 Javascript 但它没有帮助。显然,引用 Jquery 的第一个错误消失了,但我无法获得预期的结果(在这种情况下,image/jpeg在带有 的 div 中id="uploadOutput")。

When I look at the console in IE9, I get this:

当我在 IE9 中查看控制台时,我得到以下信息:

URL Method  Result  Type    Received    Taken   Initiator   Wait??  Start?? Request??   Response??  Cache read??    Gap??
http://api.imgur.com/2/upload.xml   POST    200 application/xml 1.07 KB 7.89 s  click   2808    93  5351    0   0   0

and as body response:

并作为身体反应:

<?xml version="1.0" encoding="utf-8"?>
<upload><image><name/><title/><caption/><hash>xMCdD</hash>  
<deletehash>Nb7Pvf3zPNohmkQ</deletehash><datetime>2012-03-17 01:15:22</datetime>
<type>image/jpeg</type><animated>false</animated><width>1024</width
<height>768</height><size>208053</size><views>0</views><bandwidth>0</bandwidth></image
<links><original>http://i.imgur.com/xMCdD.jpg</original
<imgur_page>http://imgur.com/xMCdD</imgur_page>
<delete_page>http://imgur.com/delete/Nb7Pvf3zPNohmkQ</delete_page>
<small_square>http://i.imgur.com/xMCdDs.jpg</small_square>
<large_thumbnail>http://i.imgur.com/xMCdDl.jpg</large_thumbnail></links></upload>

which is all fine, but for some reason, I can't process that information into the HTML page. I validated the XML, just to be sure that wasn't the problem. It is valid, of course.

这一切都很好,但由于某种原因,我无法将该信息处理到 HTML 页面中。我验证了 XML,只是为了确保这不是问题。当然,这是有效的。

So, what's the problem with IE9?.

那么,IE9 有什么问题呢?

UPDATE:

更新:

Another way to fetch XML which works in Chrome and Firefox but not in IE9:

另一种获取 XML 的方法适用于 Chrome 和 Firefox,但不适用于 IE9:

(function() {
$('#uploadForm').ajaxForm({
        dataType: "xml",
        beforeSubmit: function(a,f,o) {
           o.dataType = $('#uploadResponseType')[0].value;
           $('#uploadOutput').html('Submitting...');
        },

        success: function(data) {
            var $xml = $( data ),
                element = $($xml).find('type').text();
                alert(element);
        }
    });
})();  

UPDATE 2:

更新 2

<!DOCTYPE html>
<html>
    <body>
    <form id="uploadForm" action="http://api.imgur.com/2/upload.xml" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="key" value="00ced2f13cf6435ae8faec5d498cbbfe">
        File: <input type="file" name="image">
        Return Type: <select id="uploadResponseType" name="mimetype">
            <option value="xml">xml</option>
        </select>
        <input type="submit" value="Submit 1" name="uploadSubmitter1">
    </form>

    <div id="uploadOutput"></div>
    </body>
</html>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
?<script>
(function() {

    var options = { 
        // target:        '#output1',   // target element(s) to be updated with server response 
        //beforeSubmit:  showRequest,  // pre-submit callback 
        success: afterSuccess,  // post-submit callback 
        complete: afterCompletion,
        // other available options: 
        //url:       url         // override for form's 'action' attribute 
        type:      'POST',        // 'get' or 'post', override for form's 'method' attribute 
        dataType:  'xml'        // 'xml', 'script', or 'json' (expected server response type) 
        //clearForm: true        // clear all form fields after successful submit 
        //resetForm: true        // reset the form after successful submit 

        // $.ajax options can be used here too, for example: 
        //timeout:   3000 
    }; 

    function process_xml(xml) {
      var type = $(xml).find('type').text() ;
      return type;
      // Find other elements and add them to your document
    }


    function afterSuccess(responseText, statusText, xhr, $form)  { 
        // for normal html responses, the first argument to the success callback 
        // is the XMLHttpRequest object's responseText property 

        // if the ajaxForm method was passed an Options Object with the dataType 
        // property set to 'xml' then the first argument to the success callback 
        // is the XMLHttpRequest object's responseXML property 

        // if the ajaxForm method was passed an Options Object with the dataType 
        // property set to 'json' then the first argument to the success callback 
        // is the json data object returned by the server 
        var $xml = process_xml(responseText);
        console.log('success: ' + $xml);
    } 


    function afterCompletion(xhr,status){
          if(status == 'parsererror'){

            xmlDoc = null;

            // Create the XML document from the responseText string

            if(window.DOMParser) {

              parser = new DOMParser();
              xml = parser.parseFromString(xhr.responseText,"text/xml");

            } else {

              // Internet Explorer
              xml = new ActiveXObject("Microsoft.XMLDOM");
              xml.async = "false";
              xml.loadXML(xhr.responseText);

            }

          }

          console.log('complete: ' + process_xml(xhr.responseText));
    }

$('#uploadForm').ajaxForm(options);
})();  
</script>

Thanks in advance.

提前致谢。

回答by hohner

IE is notoriously fussy when it comes to accepting XML and parsing it. Try something like this:

IE 在接受 XML 并解析它时是出了名的挑剔。尝试这样的事情:

function process_xml(xml) {
  var type = $(xml).find('type').text() ;
  $('#type').html(type) ;

  // Find other elements and add them to your document
}

$(function() {
  $('#uploadForm').ajaxForm({ 
    dataType: "xml", // 'xml' passes it through the browser's xml parser
    success: function(xml,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.

      process_xml(xml);

      // Everything goes wrong for Internet Explorer
      // when the mime-type isn't explicitly 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){

      if(status == 'parsererror'){

        xmlDoc = null;

        // Create the XML document from the responseText string

        if(window.DOMParser) {

          parser = new DOMParser();
          xml = parser.parseFromString(xhr.responseText,"text/xml");

        } else {

          // Internet Explorer
          xml = new ActiveXObject("Microsoft.XMLDOM");
          xml.async = "false";
          xml.loadXML(xhr.responseText);

        }

        process_xml(xml);

      }
    },
    error: function(xhr,status,error)
    {
      alert('ERROR: ' + status) ;
      alert(xhr.responseText) ;
    }
  });
});

Also,use alert()throughout debugging to provide feedback on what information is being passed through at all times.

此外,alert()在整个调试过程中使用以提供有关始终通过的信息的反馈。

EDIT

编辑

The crucial thing is ensure your XML file is 'well-formed', i.e. it must notcontain any syntax errors. You need to begin the XML file with:

关键是确保您的 XML 文件格式正确,即它不能包含任何语法错误。您需要以以下内容开头 XML 文件:

<?xml version="1.0"?>

It's not so much a server issue because, the errors come from your browser(i.e. Internet Explorer) because it thinks the XML is malformed. The error comes from your browser and indicates that your XML is malformed. You can manually set what headers you want returned with these $.ajax()settings:

这不是服务器问题,因为错误来自您的浏览器(即 Internet Explorer),因为它认为 XML 格式错误。该错误来自您的浏览器,表明您的 XML 格式错误。您可以使用以下$.ajax()设置手动设置要返回的标题:

dataType: ($.browser.msie) ? "text" : "xml",
accepts: {
    xml: "text/xml",
    text: "text/xml"
}

Or another way to do the same thing is to ask for a particular header:

或者做同样事情的另一种方法是要求一个特定的标题:

headers: {Accept: "text/xml"},

The difference between the content-types application/xmland text/xmlare minor (it's based on each XML's charset), but if you want to know you can read this post.

content-typesapplication/xml和content-types 之间的区别text/xml很小(它基于每个 XML 的字符集),但是如果你想知道你可以阅读这篇文章

回答by Benno

Perhaps give this a try? I use this with a google maps store locator. I notice $.parseXML actually does this internally, but its within a try/catch, and its saying your datais null (which is weird?)

也许试试这个?我将它与谷歌地图商店定位器一起使用。我注意到 $.parseXML 实际上在内部执行此操作,但它在 try/catch 中,并且它说您的data值为 null(这很奇怪吗?)

      var xml;
     if (typeof data == "string") {
       xml = new ActiveXObject("Microsoft.XMLDOM");
       xml.async = false;
       xml.loadXML(data);
     } else {
       xml = data;
     }

From jQuery:

来自 jQuery:

// Cross-browser xml parsing
parseXML: function( data ) {
    var xml, tmp;
    try {
        if ( window.DOMParser ) { // Standard
            tmp = new DOMParser();
            xml = tmp.parseFromString( data , "text/xml" );
        } else { // IE
            xml = new ActiveXObject( "Microsoft.XMLDOM" );
            xml.async = "false";
            xml.loadXML( data );
        }
    } catch( e ) {
        xml = undefined;
    }
    if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
        jQuery.error( "Invalid XML: " + data );
    }
    return xml;
},

回答by einstein

I have used that plugin before. If I recall this right it is using an iframe to fetch the information and then it is reading the content in the iframe. The content is stored in the property responseText. But IE may have stricter rules than other browsers. Have you tried printing out the value of data.responseText?

我以前用过那个插件。如果我没记错的话,它是使用 iframe 来获取信息,然后它正在读取 iframe 中的内容。内容存储在属性 responseText 中。但是 IE 可能比其他浏览器有更严格的规则。您是否尝试打印出 data.responseText 的值?

If the value is not a XML string. I hate to say it but the API isn't made for Javascript. What I've learned is that JSONP with manipulating the script tags is the best way to do cross domain XHR. Which I don't think this plugin does.

如果该值不是 XML 字符串。我不想这么说,但 API 不是为 Javascript 设计的。我学到的是,操纵脚本标签的 JSONP 是进行跨域 XHR 的最佳方式。我认为这个插件没有。

回答by Luca Filosofi

jscode:

js代码:

    $(function() {
        $('#uploadForm').ajaxForm({
            dataType : 'xml', // OR $('#uploadResponseType option:selected').val()
            beforeSubmit : function(a, f, o) {
                $('#uploadOutput').html('Submitting...');
            },
            success : function(data) {
                var original = $(data).find('links').find('original').text();
                $('#uploadOutput').html('<img src="' + original + '" alt="" />');
            }
        });
    });

phpcode:

php代码:

<?
    $api_key = "****************************";

    $file    = getcwd() . '/' . basename( $_FILES['image']['name'] );
    move_uploaded_file($_FILES['image']['tmp_name'], $file);

    $handle  = fopen($file, "r");
    $data    = fread($handle, filesize($file));

    $pvars   = array('image' => base64_encode($data), 'key' => $api_key);
    $post    = http_build_query($pvars);

    $curl    = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'http://api.imgur.com/2/upload.xml');
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/x-www-form-urlencoded"));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $xml = curl_exec($curl); 
    curl_close ($curl);

    unlink($file);

    header('Content-type: text/xml'); 
    echo $xml;
?>