文档章节

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

 蜗牛奔跑
发布于 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

没有更多内容

加载失败,请刷新页面

加载更多

ES6

ES6:不改变原理的基础上,让API变得更简单 一、let:代替var用于声明变量 1、var的缺点: (1)声明提前 (2)没有块级作用域 2、let的优点: (1)组织了申明提前 (2)让let所在的块({}),...

wytao1995
今天
3
0
kubernetes 环境搭建 —— minikube

创建集群 minikube start 搭建好 k8s 集群后,可以查看集群的状态以及部署应用。主要用到的是 k8s 的 api,这通常需借助于 kutectl 命令行工具 基本操作 kubectl versionkubectl cluster-i...

lemos
今天
9
0
关于js混淆与反混淆还原操作

使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密,或者混淆js来达到代码保护。 1、为什么...

开源oschina
今天
11
0
用盛金公式解三次方程(ansi c版)

/* cc cubic.c -lm gcc cubic.c -lm Shengjin's Formulas Univariate cubic equation aX ^ 3 + bX ^ 2 + cX + d = 0, (a, b, c, d < R, and a!= 0). Multiple root disc......

wangxuwei
今天
9
0
JBolt开发平台入门(16)- 弹出Dialog显示指定区域的html内容

在JBolt里,有个主从表Demo。 子表中除了普通的table显示,还有其它从表显示形式 比如下方案例:是针对一个升级管理子表中存放版本的changelog富文本信息。 需求是点击左上角的弹出查看按钮,...

山东-小木
今天
46
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部