2012-03-17 14 views
9

Esta es una pregunta relacionada con this one.IE9 se niega a procesar la respuesta XML

En ACTUALIZACIÓN II, agregué un script basado en los comentarios de Jamie.

ACTUALIZACIÓN - tl; dr:

que creó un violín con una clave temporal de modo que ustedes pueden ver el problema con mayor facilidad: http://jsfiddle.net/S6wEN/.

Como esta pregunta se estaba haciendo demasiado larga, este es un resumen.

  • Intenté utilizar la API de imgur para actualizar una imagen mediante el dominio cruzado XHR.
  • Para abstraer detalles en la implementación, estoy usando el Plugin de formularios de Jquery (obviamente, está contenido en el violín).
  • Funciona muy bien en Chrome, Firefox, etc. pero no funciona en IE9.
  • El resultado esperado es actualizar la imagen y recuperar el tipo de imagen.

Todavía puede encontrar los detalles a continuación.

Gracias


que tienen este código 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> 

Así que, básicamente, que tienen una forma para subir una imagen a través de Imgur XHR entre dominios. Para administrar los detalles desagradables, estoy usando Jquery Form Plugin, que funciona bien. Sin embargo, cuando intento enviar una imagen a imgur y recibir una respuesta xml, no funciona como se espera en IE9 (no lo he probado en IE8, pero no espero grandes noticias). Funciona muy bien en Chrome y Firefox. Esta es la parte 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')); 

     } 
    }); 
})(); 

En IE9 que reciben los siguientes errores:

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

XML5619: Incorrect document syntax. 
, line 1 character 1 

También utilicé el ejemplo dado en la página de Jquery Formulario Plugin, que utiliza JavaScript, pero no ayuda . Obviamente, el primer error que hace referencia a Jquery desaparece pero no puedo obtener los resultados esperados (en este caso, image/jpeg en el div con id="uploadOutput").

Cuando miro a la consola en IE9, me sale esto:

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 

y, como respuesta del organismo:

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

que es todo muy bien, pero por alguna razón, no puedo procesar esa información en la página HTML. Validé el XML, solo para asegurarme de que ese no era el problema. Es válido, por supuesto.

Entonces, ¿cuál es el problema con IE9 ?.

ACTUALIZACIÓN:

Otra forma de obtener XML que funciona en Chrome y Firefox, pero no en 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); 
     } 
    }); 
})(); 

ACTUALIZACIÓN 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> 

Gracias de antemano .

+0

Ha ejecutado IE con Fiddler2 para inspeccionar los resultados. IE puede ser muy estricto en términos de encabezados de codificación de contenido, etc. Sospecho que aunque el documento está etiquetado como UTF-8 en el documento, es posible que el servidor no especifique un juego de caracteres. Otros navegadores con frecuencia tendrán el valor predeterminado UTF-8. – Tracker1

+0

Lo hice y ocurrió lo mismo. No lo publiqué aquí porque necesita una clave para trabajar, por lo que no tenía ningún uso práctico en este caso. Lo intentaré más tarde otra vez, sin embargo. –

+0

Acabo de agregar un violín con una clave temporal. –

Respuesta

1

Quizás esto pruebe? Lo uso con un localizador de tiendas google maps. Puedo tener $ .parseXML realmente hace esto internamente, pero su dentro de un try/catch, y su diciendo que su data es nulo

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

De jQuery (que es raro?):

// 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; 
}, 
+0

Creo que hay algo mal con la parte que no es de IE, porque ahora recibo una excepción no detectada (XML no válido: [documento de objeto]), pero en IE9 no veo ningún error, sin embargo, no hace nada incluso si el cuerpo de respuesta muestra el documento XML correcto. –

1

tengo usé ese complemento antes Si recuerdo este derecho, estoy usando un iframe para buscar la información y luego estoy leyendo el contenido en el iframe. El contenido se almacena en la propiedad responseText. Pero IE puede tener reglas más estrictas que otros navegadores. ¿Has intentado imprimir el valor de data.responseText?

Si el valor no es una cadena XML. Odio decirlo, pero la API no está hecha para Javascript. Lo que he aprendido es que JSONP con la manipulación de las etiquetas de script es la mejor manera de hacer XHR de dominio cruzado. Lo cual no creo que este plugin lo haga.

+0

Gracias por su respuesta. Cuando intenté imprimir data.responseText no obtuve nada en IE9 (aunque funciona correctamente en otros navegadores), pero la respuesta es XML válido. Además, los ejemplos en la página de documentación del complemento funcionan en IE9, así que me sorprendería mucho si esto fue causado por algo específico del complemento. –

+0

Eso confirma la hipótesis de "no tener acceso al iframe": los datos vuelven, pero no se pueden leer. – boisvert

+0

Uhm, ¿qué puedo hacer para solucionarlo? –

1

jscódigo:

$(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="" />'); 
      } 
     }); 
    }); 

phpcódigo:

<? 
    $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; 
?> 
+0

Gracias por su esfuerzo, pero tal vez no haya leído el enlace (http://stackoverflow.com/questions/9695586/cross-domain-xhr-uploading-via-javascript). Estoy buscando una solución XHR Javascript de dominio cruzado. –

5

IE es notoriamente quisquilloso a la hora de aceptar XML y analizarlo. Intentar algo como esto:

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) ; 
    } 
    }); 
}); 

También, el uso alert() largo de depuración para proporcionar información sobre qué información se está pasando a través en todo momento.

EDITAR

Lo importante es asegurarse de que su archivo XML es 'bien formados', es decir, que no debe contener errores de sintaxis. Es necesario para iniciar el archivo XML con:

<?xml version="1.0"?> 

Está no es tanto un problema del servidor, ya que, los errores provienen de su navegador (es decir, Internet Explorer), ya que cree que el XML es un formato incorrecto. El error proviene de su navegador e indica que su XML está mal formado.Puede configurar manualmente lo encabezados que desea obtener con estos ajustes: $.ajax()

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

u otra manera de hacer la misma cosa es pedir una cabecera especial:

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

La diferencia entre el contenido- los tipos application/xml y text/xml son de menor importancia (se basan en el juego de caracteres de cada XML), pero si quiere saber puede leer this post.

+0

Creo que lo has clavado. success() no se llama y complete() se ejecuta pero obviamente no recibe ninguna respuesta. Según su comentario, falta el encabezado text/xml. Revisé los encabezados en IE y en su lugar veo Tipo de contenido: application/xml. ¿No es eso suficiente? En cualquier caso, eso es un problema de servidor, ¿verdad ?. –

+0

¿Funciona cuando recibe application/xml como encabezado de respuesta? Si no, he incluido una edición rápida en mi pregunta que establece manualmente los encabezados de respuesta para la solicitud de AJAX – hohner

+0

Bueno, parece estar más cerca de la solución, pero desafortunadamente, agregar cualquiera de esos fragmentos provoca cargar la página xml de imgur.com (en Chrome, Firefox e IE). Y el éxito no comienza. –

Cuestiones relacionadas