異步上傳文件並獲得返回值(完全跨域)


  http://blog.csdn.net/lrz1011/article/details/7913992

異步上傳文件並獲得返回值(完全跨域)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傳輸的)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM