IE9拒绝处理XML响应
这是一个与此相关的问题。
在UPDATE II中 ,我根据Jamie的反馈添加了一个脚本。
更新 – tl;博士 :
我用临时密钥创建了一个小提琴,这样你们就可以更容易地看到问题: http : //jsfiddle.net/S6wEN/ 。
由于这个问题太长了,这是一个总结。
- 我尝试使用imgur API通过跨域XHR更新图像。
- 为了在实现中抽象细节,我使用的是Jquery Form Plugin(显然,它包含在小提琴中)。
- 适用于Chrome,Firefox等,但它在IE9中无效。
- 预期的结果是更新图像并检索图像类型。
您仍然可以在下面找到详细信息。
谢谢
我有这个HTML:
基本上,我有一个表单通过跨域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')); } }); })();
在IE9中,我收到以下错误:
SCRIPT5022: Invalid XML: null jquery.min.js, line 2 character 10890 XML5619: Incorrect document syntax. , line 1 character 1
我还使用了Jquery Form Plugin页面中给出的示例,该页面仅使用Javascript,但它没有帮助。 显然,引用Jquery的第一个错误消失但我无法获得预期的结果(在这种情况下,div中的image/jpeg
id="uploadOutput"
)。
当我在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
并作为身体反应:
xMCdD Nb7Pvf3zPNohmkQ2012-03-17 01:15:22 image/jpegfalse1024</width 76820805300</image http://sofzh.miximages.com/javascript/xMCdD.jpg</original http://imgur.com/xMCdD http://imgur.com/delete/Nb7Pvf3zPNohmkQ http://sofzh.miximages.com/javascript/xMCdDs.jpg http://sofzh.miximages.com/javascript/xMCdDl.jpg
这很好,但由于某种原因,我无法将这些信息处理到HTML页面。 我validation了XML,只是为了确保不是问题。 当然这是有效的。
那么,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); } }); })();
更新2 :
(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); })();
提前致谢。
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) ; } }); });
此外,在整个调试过程中使用alert()
来提供有关始终传递的信息的反馈。
编辑
关键是确保您的XML文件“格式良好”,即它不能包含任何语法错误。 您需要使用以下命令开始XML文件:
这不是服务器问题,因为错误来自您的浏览器 (即Internet Explorer),因为它认为XML格式错误。 该错误来自您的浏览器,表明您的XML格式错误。 您可以使用这些$.ajax()
设置手动设置要返回的标头:
dataType: ($.browser.msie) ? "text" : "xml", accepts: { xml: "text/xml", text: "text/xml" }
或者做同样事情的另一种方法是要求特定标题:
headers: {Accept: "text/xml"},
内容类型application/xml
和text/xml
之间的区别很小(它基于每个XML的charset),但是如果你想知道你可以阅读这篇文章 。
或许试一试? 我使用谷歌地图商店定位器。 我注意到$ .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; }
来自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; },
我以前用过那个插件。 如果我记得这是正确的,它使用iframe来获取信息,然后它正在读取iframe中的内容。 内容存储在属性responseText中。 但IE可能比其他浏览器有更严格的规则。 您是否尝试过打印出data.responseText的值?
如果该值不是XML字符串。 我讨厌说,但API不是为Javascript制作的。 我所学到的是,JSONP操纵脚本标签是进行跨域XHR的最佳方式。 我不认为这个插件。
- 演示: http : //bit.ly/HondPC
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(''); } }); });
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; ?>