【完全跨域】异步上传文件并获得返回值

AJAX可以进行数据的异步请求,但对于文件跨域问题却束手无策。

Jsonp可以进行跨域数据的异步请求,但同样不能使用于文件。

<form>表单可以进行跨域数据和文件的上传,但却会使页面跳转。

那么如何同时实现“异步”+“跨域”+“文件”+“返回值”这几个特性呢?方法如下:

原理:

将<form>表单通过一个iframe来submit,也就是将<form>的target属性设置为一个iframe的id,这样<form>的action URL就会在这个iframe中打开,那么服务器的返回数据也就会输出到iframe中了。最后再通过主页面与iframe之间的交互完成对返回数据的读取(这涉及到跨域问题,文章后面将介绍此问题的解决方法)。

基本结构:

前端部分(当前域名:www.test.com,与form中的action域名相同)

1 <form action="http://www.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
2  
3         <input type="file" name="upload_file" />
4  
5         <input type="submit" value="开始上传" />
6  
7 </form>
8  
9 <iframe name="upload" style="display:none"></iframe> // 注意,是name="upload",而不是id="upload"

后台部分

1 <?php
2  
3         move_uploaded_file($_FILES[‘upload_file‘][‘tmp_name‘],‘upload/‘ $_FILES[‘upload_file‘][‘name‘]); // 存储上传的文件
4  
5         echo ‘This data is from server!‘// 返回数据,这行字将输出到iframe的body中
6  
7 ?>

优化结构一:

前端部分(当前域名:a.test.com,与form中的action域名不同)

01 <form action="http://b.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
02  
03         <input type="file" name="upload_file" />
04  
05         <input type="text" name="script" value="http://a.test.com/JS/iframe_control.src.js" style="display:none" /> // 注意这里!
06  
07         <input type="submit" value="开始上传" />
08  
09 </form>
10  
11 <iframe name="upload" style="display:none"></iframe> // 注意,是name="upload",而不是id="upload"
12  
13 <script type="text/javascript">
14  
15         document.domain="test.com"; // 解决与iframe之间的跨域问题
16  
17 </script>

后台部分

01 <?php
02  
03         move_uploaded_file($_FILES[‘upload_file‘][‘tmp_name‘],‘upload/‘ $_FILES[‘upload_file‘][‘name‘]); // 存储上传的文件
04  
05         $html ‘<html><head>‘
06  
07                     ‘<script src="‘ $_POST[‘script‘] .‘" type="text/javascript"></script>‘ // 注意这里!
08  
09                     ‘</head><body>‘
10  
11                     ‘This data is from server!‘ // 返回数据,这行字将输出到iframe的body中
12  
13                     ‘</body></html>‘;
14  
15         echo $html;
16  
17 ?>

通过上面的优化,iframe从服务器接收到的内容中就多了一条<script>标签,这个标签的src是由<form>表单提交的,也就是说这个js文件可

以放在任何域名下,并且通过修改该js的内容来制定这个iframe的功能。比如,在其中调用document.doain="test.com"后,便可以与主页面

互相通信与控制了(主页面中也调用了document.domain="test.com",因此跨域限制被消除了)。

优化结构二:

前端部分(当前域名:www.a.com,与form中的action域名不同)

01 <form action="http://www.b.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
02  
03         <input type="file" name="upload_file" />
04  
05         <input type="text" name="tmpurl" value="http://www.a.com/tmp.html" style="display:none" /> //注意这里!
06  
07         <input type="submit" value="开始上传" />
08  
09 </form>
10  
11 <iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"

这次我们没有看到<script>标签,因为不再需要了,请继续看后台代码:

后台部分

1 <?php
2  
3         move_uploaded_file($_FILES[‘upload_file‘][‘tmp_name‘],‘upload/‘ $_FILES[‘upload_file‘][‘name‘]); // 存储上传的文件
4  
5         $data ‘This data is from server!‘ // 返回数据,这行字将通过URL返回给浏览器
6  
7         header(‘Location:‘ $_POST[‘tmpurl‘] . ‘?data=‘ $_data); // 上传完成后使iframe直接跳转至$_POST[‘tmpurl‘]
8  
9 ?>

与优化结构一不同的是,结构二中不再使用“指定document.domain为一级域名”来解除跨域限制,也不通过iframe的document内容来得到返

回数据,而是通过使iframe直接跳转至当前域名(通过$_POST[‘tmpurl‘]指定)来彻底取消跨域限制并且通过url的search部分传递返回数据。

两种结构的对比:

跨域:优化结构一只可解决一级域名相同的情况下的跨域情况,而优化结构二可解决任何跨域,比如百度与google之间。

数据:优化结构一的返回数据无大小限制,而优化结构二的返回数据必须小于2K(因为数据是通过RUL传输的)。

时间: 2024-12-24 17:54:23

【完全跨域】异步上传文件并获得返回值的相关文章

异步上传文件并获得返回值(完全跨域)

http://blog.csdn.net/lrz1011/article/details/7913992 异步上传文件并获得返回值(完全跨域)AJAX可以进行数据的异步请求,但对于文件和跨域问题却束手无策. Jsonp可以进行跨域数据的异步请求,但同样不能使用于文件. <form>表单可以进行跨域数据和文件的上传,但却会使页面跳转. 那么如何同时实现“异步”+“跨域”+“文件”+“返回值”这几个特性呢?方法如下: 原理: 将<form>表单通过一个iframe来submit,也就是

(H5)FormData+AJAX+SpringMVC跨域异步上传文件

最近都没时间整理资料了,一入职就要弄懂业务,整天被业务弄得血崩. 总结下今天弄了一个早上的跨域异步上传文件.主要用到技术有HTML5的FormData,AJAX,Spring MVC. 首先看下上传页面: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script type="text/javascript" src="js/plugins/

Jquery~跨域异步上传文件

先说明白 这个跨域异步上传功能我们借助了Jquery.form插件,它在异步表单方面很有成效,而跨域我们会在HTTP响应头上添加access-control-allow-method,当然这个头标记只有IE10,火狐和谷歌上支持,对于IE10以下的浏览器来说,我们就不能用这种方式了,我们需要换个思路去干这事,让服务端去重写向我们的客户端,由客户端(与文件上传页面在同域下)来返回相关数据即可. 再做事 1 Jquery.form的使用 <form method="post" act

cors跨域 + 异步上传文件

一:实现跨域 CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问.CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求.实现此功能非常简单,只需由服务器发送一个响应标头即可. 如果不需要文件上传,可以使用jquery.ajax,设置dataType="jsonp",即可(注意:jsonp的请求格式与返回数据与json有些许差入). 1.使用jQuery的support属性,其下有一个cors设置,设置成true,说名此次请求需要验证该请求是否允许跨域 即:$.su

form上传文件以及跨域异步上传

要设置了enctype属性才能上传,需要使用上传的jar包,这里使用的是cos-26Dec2008.jar, 而且后台获取值的时候,getfile要放在第一位 一次设置好上传格式后没有上传文件,也就没有getFile,结果总是取不到值,删掉enctype="multipart/form-data"属性就ok了. 关于跨域上传文件: 跨域上传文件总会报错,即使服务器端设置了header('Access-Control-Allow-Origin: *'),仍会报错说缺少multipart属

ASP.NET MVC 使用jquery.form.js 异步上传 在IE下返回值被变为下载的解决办法

错误记录: <script type="text/javascript"> $(function () { $(document).off("ajaxSend"); //异步上传 $("#Submit").click(function () { if ($("#selectFileButton").val() == "") { return false; } $("#fileForm&

struts2 jquery ajaxFileUpload 异步上传文件

一.ajaxFileUpload 实现异步上传文件利用到了ajaxFileUpload.js这个文件,这是别人开发的一个jquery的插件,可以实现文件的上传并能够和struts2框架和好的融合在一起.但是网上的提供的一些ajaxFileUpload.js插件存在一些问题,不能够实现多次点击上传文件,要想再次上传必须重新刷新页面.在网上找了好久才找到真正的解决方案,有些网友给出的解决方案并没有真正的解决问题,不知到什么原因.我的修改: 原文件: var oldElement = $('#' +

【转】JQuery插件ajaxFileUpload 异步上传文件(PHP版)

前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错,但是由于手机不支持flash,所以不得不再找一个文件上传插件来用了.后来发现ajaxFileUpload这个插件挺不错,所以就用这个插件来做异步上传文件的效果.网上也有很多对ajaxFileUpload插件的使用的文章,不过我发现没有PHP版,所以这次服务器那边的处理就使用PHP语言来处理. 一.先对ajaxFileUpload插件的语法参数进行讲解 原理:ajaxfileu

JQuery插件ajaxFileUpload 异步上传文件(PHP版)

太久没写博客了,真的是太忙了.善于总结,进步才会更快啊.不多说,直接进入主题. 前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错,但是由于手机不支持flash,所以不得不再找一个文件上传插件来用了.后来发现ajaxFileUpload这个插件挺不错,所以就用这个插件来做异步上传文件的效果.网上也有很多对ajaxFileUpload插件的使用的文章,不过我发现没有PHP版,所以这次服务器那边的处理就使用PHP语言来处理. 一.