Extjs的form跨域提交文件时,无法获取返回结果
form文件表单跨域提交时,无法获取远程服务器的返回结果,form提交代码如下:
form.submit({ url:'http://{remoteUrl}/hgisserver/wrds/file', waitMsg: 'Reading your file...', method : 'POST', success: function(fp, o) { console.log(o); }, failure: function(form, action) { console.log(action); } });
报错如下:
"{success:false,message:"Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame."}"
为解决这个问题,中间比较坎坷,http://blog.csdn.net/caostorm/article/details/74392158该博客的解决办法,我在extjs-4.2.1版本下试了没有效果,Content-Type仍然为text/plain.
现总结得到如下两种解决方案:
远程服务器已经设置了跨域请求,文件已经上传到远程服务器了,只是由于form新开的iframe无法接收服务器的返回结果。解决办法如下:
1、通过PHP代理转发请求和返回结果;
2、采用jquery的ajax请求;
第一种方法比较复杂,需设置php环境,避免文件过大无法上传,若直接将临时文件转发,文件名的传入还需在后台解析时注意;
form提交时代吗修改为:
form.submit({ url: '/php/formCrosUpload.php', params:{ remoteUrl: "http://{remoteUrl}/hgisserver/wrds/file" } waitMsg: 'Reading your file...', method : 'POST', success: function(fp, o) { console.log(action); }, failure: function(form, action) { console.log(action); } });
php处理:
<?php header("Access-Control-Allow-Origin:*"); header("Access-Control-Allow-Methods:POST"); function curlPost($url,$postData) { $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_POST, count($postData)); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); $output=curl_exec($ch); curl_close($ch); return $output; } $url = trim($_POST['remoteUrl']); $file = $_FILES['form-file']; $tmpFile = $file["tmp_name"]; if($file["error"] > 0){ echo "file upload error:".$file["error"]; } else{ $post_data = array ( $file['name'] => '@'. $tmpFile //将文件名通过Field的key传入,后台解析时需注意,$tmpFile是临时文件,文件名为null ); echo curlPost($url,$post_data); } ?>
在工程配置web.xml文件制定的php.ini配置文件中设置设置php的文件上传大小限制:
web.xml: ...... <init-param> <param-name>ini-file</param-name> <param-value>WEB-INF/php.ini</param-value> </init-param> ...... php.ini: upload_max_filesize = 50M //最大上传文件大小 post_max_size = 50M //最大POST大小 memory_limit = 128M //内存限制 max_execution_time = 30 //最大执行时间 max_input_time = 60 //最大输入时间
第二种方法比较简单,可增加等待提示框,实现与form提交等待同样的效果;通过FormData装载form文件,然后POST到远程服务器
代码如下:
var fileEl = Ext.getCmp('form-file').fileInputEl.dom; var fd = new FormData(); fd.append("file", fileEl.files[0]); var msg = new Ext.window.MessageBox(); msg.wait('Upload your file...'); $.ajax({ url: 'http://{remoteUrl}/hgisserver/wrds/file', type: 'POST', cache: false, data: fd, processData: false, contentType: false, dataType:"json", beforeSend: function(){ uploading = true; }, success : function(data) { console.log(data); form.reset(); }, error: function(data) { Ext.Msg.alert('Fail', 'Upload File failed.'); }, complete: function(){ msg.close(); } });