Parsing xml/json response in IE9

2019-02-28 11:24发布

问题:

I thought this issue was resolved but unfortunately it's not, although it seems to be a different problem this time.

I want to use imgur API photo sharing service via cross domain XHR, and apparently, it works fine. I start a request, they send an xml and all I need to do is processing that. However, I can't do it properly in Internet Explorer 9 despite multiple suggestions (works in Chrome, Firefox). This is the most simple code I tried:

HTML:

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

There you can see a key to Imgur API (you can use it, if you want... it's only for testing purposes, but I don't thing there is anything wrong with the xml response I receive).

I'm using Jquery Form Plugin to manage the file uploads.

XML:


This is the simplest piece of code that I have tested. Usually, we need to help Internet Explorer to parse xml independently, that's why I have parseXml.

Javascript:

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

$('#uploadForm').ajaxForm({
    dataType: ($.browser.msie) ? "text" : "xml",
    accepts: {
        xml: "text/xml",
        text: "text/xml"
    },
    // has been received
    success: function(data) {
        $('#uploadOutput').html('Submitting...');
        data = parseXml(data);
        console.log(data);
        alert(data);
    },
    complete: function(data) {
        $('#uploadOutput').html('Complete...');
     }
});

dataType: ($.browser.msie) ? "text" : "xml" supposedly tells IE to return a text response. Despite all these assurances, the Content Type of the response is application/xml (I was told that wasn't a problem). As an xml I receive this:

<?xml version="1.0" encoding="utf-8"?>
<upload><image><name/><title/><caption/><hash>087Y0</hash><deletehash>gUcgywjXoJyAJp6</deletehash><datetime>2012-06-02 21:59:35</datetime><type>image/jpeg</type><animated>false</animated><width>1024</width><height>768</height><size>297623</size><views>0</views><bandwidth>0</bandwidth></image><links><original>http://i.imgur.com/087Y0.jpg</original><imgur_page>http://imgur.com/087Y0</imgur_page><delete_page>http://imgur.com/delete/gUcgywjXoJyAJp6</delete_page><small_square>http://i.imgur.com/087Y0s.jpg</small_square><large_thumbnail>http://i.imgur.com/087Y0l.jpg</large_thumbnail></links></upload>

I think it looks ok and I can parse it in other browsers using something like $($.parseXml(xml)).find('original').text(), but not in IE9. So basically, I'm receiving a response but I can't parse that xml, although when I try to figure out what I'm getting in IE, looks like I get nothing.

Furthermore, success is not even firing which is a signal that IE9 couldn't parse the xml. complete is firing but it doesn't receive anything as data. So what am I doing wrong?

Here you can have a fiddle (includes Jquery Form Plugin).

UPDATE:

JSON


For future reference, JSON will not work using Jquery Form Plugin in this situation. From the documentation:

The iframe element is used as the target of the form's submit operation 
which means that the server response is written to the iframe. This is fine 
if the response type is HTML or XML, but doesn't work as well if the response 
type is script or JSON, both of which often contain characters that need to 
be repesented using entity references when found in HTML markup. To account 
for the challenges of script and JSON responses when using the iframe mode, 
the Form Plugin allows these responses to be embedded in a textarea element 
and it is recommended that you do so for these response types when used in 
conjuction with file uploads and older browsers.

Ideas?.

Thanks!

回答1:

This is due to the Cross-domain security, called Same Origin Policy.

This plugin uses the File API if it's implemented by the browser (as in Chrome for example) and, if not, it uses a neat trick of creating a hidden iframe and posting data to it. In the case of the address being on another domain, the plugin can't get the data from the iframe, so it fail.

Try enabling the debug mode of the plugin with: $.fn.ajaxSubmit.debug = true; and you will see what is happening behind the scenes.

Unfortunataly, the only way of doing the upload is by using a hidden iframe in your HTML, not added by script, and force the post to it by passing the parameter iframeTarget with the selector for this iframe, but you will not be able to grab the response, because of the above mentioned problem (I don't know why the iframe generated by the plugin don't post the data):

JS:

$('#uploadForm').ajaxForm({
    iframeTarget: ($.browser.msie) ? "#iframeTarget" : false,
    ...

HTML:

<iframe name="iframeTarget" id="iframeTarget">This iframe can be hidden with CSS</iframe>

You can also make use of conditional comments to hide the iframe from other browsers:

<!--[if IE]>
<iframe name="iframeTarget" id="iframeTarget">This iframe can be hidden with CSS</iframe>
<![endif]-->

A note on this is that the success callback will not fire.

Edit:

Has this site you are communication with a JSON response option?

If it has, you can use jsonp as the dataType parameter, add ?callback=someFunction to the end of the url and write the someFunction(data){} that receives the data and parses it the same way your success callback.