-
通过iframe实现无刷新跨域异步上传图片
网络 2014/10/31 9:56:52由于我们公司的图片服务是单独的项目,在我使用ajax表单异步提交的时候出现了Permission denied to access property 'ownerDocument',然后开始了我的跨域上传文件解决之路。
查了很多文档,大致有以下几种思路:
1.使用flash插件(比如uploadify,swfupload)做图片上传组件,可以实现跨域上传,我们项目中也在用,只要在图片服务的服务端放置一个crossdomain文件,定义允许访问的域名地址就可以。
2.假如a项目要上传图片到b服务中,在a项目写一个中转后台,模拟http表单提交,我想尝试,但是httpclient的MultipartPostMethod都已经标注为废弃了,也找不到其他方法,遂放弃。
3.看到一条博文说可以将b服务在hosts里面配置成upload.www.a.com就可以解决该问题,试了一下根本不行
4.通过iframe实现表单无刷新提交,而且我发现kindeditor的图片上传思路也是如此,正好我也要用这个编辑器,就一起把此问题解决了
思路大致如下:将表单提交的target设置到一个隐藏的iframe中,这样就算表单提交,刷新的也是隐藏的iframe,而不是整个页面,由于跨域提交的话,子iframe和主页面还是不能通信和相互访问,所以在b服务的图片保存之后做一个重定向到a服务的一个html页面,这样在浏览器看来就不再是跨域上传了,最后在这个过程中还要考虑中文乱码问题,我用的是spring web mvc 框架,重定向的时候使用ModelAndView来做的就不会出现乱码的情况,但是用response就会,就算我设置了编码格式仍然没有用,让我很迷惑,最后贴代码。
首先是upload.html
<script type="text/javascript"> function callback(json){ var data = eval('(' + json + ')'); alert(data.result + data.key + data.msg); } </script> </head> <body> <form id="postForm1" method="post" action="http://www.b.com/upload?redirectUrl=http://www.a.com/test.html" enctype="multipart/form-data" target="hidden_frame"> <input type="text" name="type" value="pictorialPic" /> <input type="file" name="Filedata" id="upload1"/> </form> <iframe name='hidden_frame' id="hidden_frame" style='display:none'></iframe>
然后是重定向后的页面test.html
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript"> window.onload = function() { var rs = decodeURI(window.location).split('?').slice(1); //decodeURI是为了兼容中文解码 var list = rs.toString().split("&"); var msg; var result; var json='{';//最终还是获取json对象,这样kindeditor也可以用 for(var i = 0; i<list.length; i++){ var list1 = list[i].split('='); if(i != 0){ json += ',' } json += '"' + list1[0] + '":"' + list1[1] + '"'; } json += '}'; if(window.parent.callback != null){ window.parent.callback(json); //这是针对普通上传 }else{ document.body.innerHTML += '<pre>' + json + '</pre>';//这是针对kindeditor框架可以获取到json对象 } } </script> </head> <body> </body> </html>
最后是b服务上的图片上传后的重定向
待图片上传的逻辑写完之后,能够获取到图片的路径或者是失败的原因,针对使用spring mvc的写法StringBuffer sBuffer2 = new StringBuffer("redirect:").append(redirectUrl);
ModelAndView modelAndView = new ModelAndView(sBuffer2.toString());
for (String key : map.keySet()) {
modelAndView.addObject(key, map.get(key));//将返回的参数设置到modelAndView中,最后也是以?之后带的参数出现
}
return modelAndView;
如果自定义的json格式和kindeditor的格式不一致,修改../kindeditor/plugins/image/image.js文件的191行的afterUpload回调函数即可
至此终于完成了我的表单提交跨域图片上传之路。
阅读(2231) 分享(0)