文档章节

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

 蜗牛奔跑
发布于 2015/11/02 12:34
字数 1106
阅读 822
收藏 2

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

作者:php-note.com  发布于:2015-03-01 10:58  分类:JS/jQuery  浏览(595)

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.domain="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传输的)。


本文转载自:

粉丝 38
博文 615
码字总数 118352
作品 0
海淀
私信 提问
加载中

评论(1)

陈信贤001
mark
异步上传文件并获得返回值(完全跨域)

异步上传文件并获得返回值(完全跨域) AJAX可以进行数据的异步请求,但对于文件和跨域问题却束手无策。 Jsonp可以进行跨域数据的异步请求,但同样不能使用于文件。 <form>表单可以进行跨域数...

跑龙套
2014/03/10
7.3K
0
OkHttp3简单使用教程(一):请求和响应

一,HTTP请求、响应报文格式 要弄明白网络框架,首先需要先掌握Http请求的,响应的报文格式。 HTTP请求报文格式: HTTP请求报文主要由请求行、请求头部、请求正文3部分组成. request.png 请求...

木有粗面_9602
2018/01/13
0
0
使用JQuery ajaxFileUpload.js上传文件踩坑记录

前言 最近在做前端的时候要实现文件上传的功能,用了form和jquery的ajax传值效果都不理想,最后采用了这个前端脚本来实现。在使用的时候遇到了几个坑,一路摸着石头过河,也算是解决了问题,...

杳杳靈鳯
2018/10/23
0
0
点击图片上传文件

一、选择文件 1、隐藏input(大部分手机浏览器,微信中都不可用) 通过js触发选择文件。js获取选择的文件并上传 实现: 上传

陈安一
2015/08/31
0
0
jQuery插件之ajaxFileUpload上传文件

ajaxFileUpload.js 很多同名的,因为做出来一个很容易。 我用的是这个:https://github.com/carlcarl/AjaxFileUpload 下载地址在这里:http://files.cnblogs.com/files/kissdodog/ajaxfileup...

hello菜bird
2016/12/01
151
0

没有更多内容

加载失败,请刷新页面

加载更多

Android面试常客之Handler全解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/fnhfire_7030/article/details/79518819 前言:又到了一年...

shzwork
7分钟前
0
0
position sticky 定位

本文转载于:专业的前端网站➫position sticky 定位 1、兼容性 https://caniuse.com/#search=sticky chrome、ios和firefox兼容性良好。 2、使用场景 sticky:粘性。粘性布局。 在屏幕范围内时...

前端老手
13分钟前
1
0
CentOS 7 yum 安装 PHP7.3 教程

参考:https://www.mf8.biz/centos-rhel-install-php7-3/ 1、首先安装 EPEL 源: yum install epel-release 安装 REMI 源: yum install http://rpms.remirepo.net/enterprise/remi-release......

dragon_tech
28分钟前
1
0
Linux物理网卡聚合及桥接

Linux内部实现的bridge可以把一台机器上的多张网卡桥接起来,从而把自己作为一台交换机。同时,LInux bridge还支持虚拟端口,即桥接的不一定都是物理网卡接口,还可以是虚拟接口。目前主要表...

xiangyunyan
29分钟前
1
0
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

猿敲月下码
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部