zoukankan      html  css  js  c++  java
  • 异步上传文件并获得返回值(完全跨域)

    1. 异步上传文件并获得返回值(完全跨域)AJAX可以进行数据的异步请求,但对于文件和跨域问题却束手无策。  
    2.   
    3. Jsonp可以进行跨域数据的异步请求,但同样不能使用于文件。  
    4.   
    5. <form>表单可以进行跨域数据和文件的上传,但却会使页面跳转。  
    6.   
    7. 那么如何同时实现“异步”+“跨域”+“文件”+“返回值”这几个特性呢?方法如下:  
    8.   
    9. 原理:  
    10.   
    11. 将<form>表单通过一个iframe来submit,也就是将<form>的target属性设置为一个iframe的id,这样<form>的action URL就会在这个iframe中  
    12.   
    13. 打开,那么服务器的返回数据也就会输出到iframe中了。最后再通过主页面也iframe之间的交互完成对返回数据的读取(这涉及到跨域问题,  
    14.   
    15. 文章后面将介绍此问题的解决方法)。  
    16.   
    17.   
    18.   
    19. 基本结构:  
    20.   
    21. 前端部分(当前域名:www.test.com,与form中的action域名相同)  
    22.   
    23.   
    24. <form action="http://www.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">  
    25.   
    26.         <input type="file" name="upload_file" />  
    27.   
    28.         <input type="submit" value="开始上传" />  
    29.   
    30. </form>  
    31.   
    32. <iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"  
    33.   
    34. 后台部分  
    35.   
    36. <?php  
    37.   
    38.         move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件  
    39.   
    40.   
    41.         echo 'This data is from server!'; //返回数据,这行字将输出到iframe的body中  
    42.   
    43.   
    44. ?>  
    45.   
    46. 优化结构一:  
    47.   
    48. 前端部分(当前域名:a.test.com,与form中的action域名不同)  
    49.   
    50. <form action="http://b.test.com/io.php" method="POST" enctype="multipart/form-data" target="upload">  
    51.   
    52.         <input type="file" name="upload_file" />  
    53.   
    54.         <input type="text" name="script" value="http://a.test.com/JS/iframe_control.src.js" style="display:none" /> //注意这里!  
    55.   
    56.   
    57.         <input type="submit" value="开始上传" />  
    58.   
    59. </form>  
    60.   
    61. <iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"  
    62.   
    63. <script type="text/javascript">  
    64.   
    65.         document.domain="test.com"; //解决与iframe之间的跨域问题  
    66.   
    67. </script>  
    68.   
    69. 后台部分  
    70.   
    71. <?php  
    72.   
    73.         move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件  
    74.   
    75.   
    76.         $html = '<html><head>'  
    77.   
    78.                     . '<script src="' . $_POST['script'] .'" type="text/javascript"></script>' //注意这里!  
    79.   
    80.                     . '</head><body>'  
    81.   
    82.                     . 'This data is from server!' //返回数据,这行字将输出到iframe的body中  
    83.   
    84.                     . '</body></html>';  
    85.   
    86.         echo $html;  
    87.   
    88.   
    89. ?>  
    90.   
    91.   
    92. 通过上面的优化,iframe从服务器接收到的内容中就多了一条<script>标签,这个标签的src是由<form>表单提交的,也就是说这个js文件可  
    93.   
    94. 以放在任何域名下,并且通过修改该js的内容来制定这个iframe的功能。比如,在其中调用document.doain="test.com"后,便可以与主页面  
    95.   
    96. 互相通信与控制了(主页面中也调用了document.domain="test.com",因此跨域限制被消除了)。  
    97.   
    98.   
    99. 优化结构二:  
    100.   
    101.   
    102. 前端部分(当前域名:www.a.com,与form中的action域名不同)  
    103.   
    104. <form action="http://www.b.com/io.php" method="POST" enctype="multipart/form-data" target="upload">  
    105.   
    106.         <input type="file" name="upload_file" />  
    107.   
    108.         <input type="text" name="tmpurl" value="http://www.a.com/tmp.html" style="display:none" /> //注意这里!  
    109.   
    110.   
    111.         <input type="submit" value="开始上传" />  
    112.   
    113. </form>  
    114.   
    115. <iframe name="upload" style="display:none"></iframe> //注意,是name="upload",而不是id="upload"  
    116.   
    117. 这次我们没有看到<script>标签,因为不再需要了,请继续看后台代码:  
    118.   
    119.   
    120. 后台部分  
    121.   
    122. <?php  
    123.   
    124.         move_uploaded_file($_FILES['upload_file']['tmp_name'],'upload/' . $_FILES['upload_file']['name']); //存储上传的文件  
    125.   
    126.         $data = 'This data is from server!' //返回数据,这行字将通过URL返回给浏览器  
    127.   
    128.   
    129.         header('Location:' . $_POST['tmpurl'] . '?data=' . $_data); //上传完成后使iframe直接跳转至$_POST['tmpurl']  
    130.   
    131. ?>  
    132.   
    133.   
    134. 与优化结构一不同的是,结构二中不再使用“指定document.domain为一级域名”来解除跨域限制,也不通过iframe的document内容来得到返  
    135.   
    136. 回数据,而是通过使iframe直接跳转至当前域名(通过$_POST['tmpurl']指定)来彻底取消跨域限制并且通过url的search部分传递返回数据。  
    137.   
    138. 两种结构的对比:  
    139.   
    140. 跨域:优化结构一只可解决一级域名相同的情况下的跨域情况,而优化结构二可解决任何跨域,比如百度与google之间。  
    141.   
    142. 数据:优化结构一的返回数据无大小限制,而优化结构二的返回数据必须小于2K(因为数据是通过RUL传输的)。 
  • 相关阅读:
    C# Note23: 如何自定义类型使用foreach循环
    C# Note22: 《Effective C#》笔记
    C# Note21: 扩展方法(Extension Method)及其应用
    C# Note20: 制作延时改变显示的标题栏
    C# Note19: Windows安装包制作实践
    Python Note1: Pycharm的安装与使用
    java Html&JavaScript面试题:HTML 的 form 提交之前如何验证数值文本框的内容全部为数字? 否则的话提示用户并终止提交?
    java Html&JavaScript面试题:用table显示n条记录,每3行换一次颜色,即1,2,3用红色字体,4,5,6用绿色字体,7,8,9用红颜色字体。
    java Html&JavaScript面试题:判断第二个日期比第一个日期大
    java算法面试题:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
  • 原文地址:https://www.cnblogs.com/xuqiudong/p/4464926.html
Copyright © 2011-2022 走看看