文档章节

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

跑龙套
 跑龙套
发布于 2014/03/10 15:56
字数 1009
阅读 7272
收藏 19

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

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

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

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

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

原理:

将<form>表单通过一个iframe来submit,也就是将<form>的target属性设置为一个iframe的id,这样<form>的action URL就会在这个iframe中

打开,那么服务器的返回数据也就会输出到iframe中了。最后再通过主页面也iframe之间的交互完成对返回数据的读取(这涉及到跨域问题,

文章后面将介绍此问题的解决方法)。

 

基本结构:

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

<form action="http://www.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">

        <input type="file" name="upload_file" />

        <input type="submit" value="开始上传" />

</form>

<iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"

后台部分

<?php

        move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件

        echo 'This data is from server!'; //返回数据,这行字将输出到iframe的body中

?>

优化结构一:

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

<form action="http://b.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">

        <input type="file" name="upload_file" />

        <input type="text" name="script" value="http://a.test.com/JS/iframe_control.src.js" style="display:none" /> //注意这里!

        <input type="submit" value="开始上传" />

</form>

<iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"

<script type="text/javascript">

        document.domain="test.com"; //解决与iframe之间的跨域问题

</script>

后台部分

<?php

        move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件

        $html = '<html><head>'

                    . '<script src="' . $_POST['script'] .'" type="text/javascript"></script>' //注意这里!

                    . '</head><body>'

                    . 'This data is from server!' //返回数据,这行字将输出到iframe的body中

                    . '</body></html>';

        echo $html;

?>

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

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

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

优化结构二:

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

<form action="http://www.b.com/io.php" method="POST" enctype="multipart/form-data" target="upload">

        <input type="file" name="upload_file" />

        <input type="text" name="tmpurl" value="http://www.a.com/tmp.html" style="display:none" /> //注意这里!

        <input type="submit" value="开始上传" />

</form>

<iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"

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

后台部分

<?php

        move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件

        $data = 'This data is from server!' //返回数据,这行字将通过URL返回给浏览器

        header('Location:' . $_POST['tmpurl'] . '?data=' . $_data); //上传完成后使iframe直接跳转至$_POST['tmpurl']

?>

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

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

两种结构的对比:

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

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

原作者:微米博客

本文转载自:http://hi.baidu.com/flondon/item/8c21c375723eff2fd7a89c95

跑龙套
粉丝 1
博文 1
码字总数 0
作品 0
南京
私信 提问
【完全跨域】异步上传文件并获得返回值

【完全跨域】异步上传文件并获得返回值 作者:php-note.com 发布于:2015-03-01 10:58 分类:JS/jQuery 浏览(595) AJAX可以进行数据的异步请求,但对于文件和跨域问题却束手无策。 Jsonp可以...

蜗牛奔跑
2015/11/02
822
1
【初窥javascript奥秘之Ajax】简述下你所知道的Ajax?

前言 ajax已经流行很多年了,现在来说它是否已经晚了呢???特别是有这样框架那样框架后,还有几个人认识原生ajax呢?我们每天都会用到的东西你到底对他了解吗? 在最近一次面试上不幸被问到...

范大脚脚
2017/12/14
0
0
重学前端(8)封装ajax,http,跨域问题

前言 当我们熟练的使用axios,fetch,promise的时候是否还会想起,当年的ajax,让我们来重温ajax原理,感受一下经典 http 协议 HTTP协议,即超文本传输协议(Hypertext transfer protocol)。是...

why前端_小牛_到犀牛
06/04
0
0
深入了解XMLHttpRequest

XMLHttpRequest 浏览器在 类上定义了他们的 HTTP API。这个类的每一个实例都表示一个独立的请求/响应,并且这个对象的属性和方法允许指定请求细节和提取响应数据。W3C在 规范的基础上制定了2...

祥同学
05/29
0
0
js/异步/跨域(文件服务器)/文件上传/大文件拆分上传,方案设计请教

需求: 通过js异步上传文件到文件服务器(跨域),并返回存放地址。 疑问点: 1. js异步文件上传实现方案 2. 文件过大,可能存在拆分上传问题 3. ajax跨域问题 4. 文件服务器,如何接受处理(...

蝴蝶和向日葵
2018/08/20
533
4

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 后来马云就一心想挣钱了

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑:《空帆船》- 朴树 《空帆船》- 朴树 手机党少年们想听歌,请使劲儿戳(这里) @webw :第二次被锁在电梯里了 上次你忘带电梯卡, ...

小小编辑
36分钟前
171
7
关于does not give a valid preprocessing token

#define VFUNC(self) ((##self##)->_vptr) 这样在gcc下会编译失败, VC不会 报pasting ) does not give a valid preprocessing token 据说是因为版本问题 解法:去掉## define VFUNC(self) (......

shzwork
37分钟前
3
0
CSS盒子模型

一、什么叫框模型 页面元素皆为框(盒子) 定义了元素框处理元素内容,内边距,外边距以及边框的计算方式 二、外边距 围绕在元素边框外的空白距离(元素与元素之间的距离) 语法:margin,定...

wytao1995
今天
5
0
Replugin借助“UI进程”来快速释放Dex

public static boolean preload(PluginInfo pi) { if (pi == null) { return false; } // 借助“UI进程”来快速释放Dex(见PluginFastInstallProviderProxy的说明) return PluginFastInsta......

Gemini-Lin
今天
4
0
Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部