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


    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传输的)。

  • 相关阅读:
    推荐.Net、C# 逆向反编译四大工具利器
    逆向工具/反编译工具 集合
    秒杀系统-并发处理
    react动态渲染组件
    通过dom获取react节点
    mac上安装windows触摸板不能右键
    STM32F103智能配网mqtt协议EMQ安卓App远程控制LED采集温湿度ESP8266
    itop4412 基于物联网技术的商品支付系统 毕业设计
    STM32F103 单片机最小系统 核心板 C8T6 MINI 飞控 小车 主控制板
    31865 MAX31865 RTD铂电阻温度检测器 PT100至PT1000传感器模块
  • 原文地址:https://www.cnblogs.com/qxbj/p/4310217.html
Copyright © 2020-2023  润新知