異步上傳文件並得到返回值(徹底跨域)

來源:http://hi.baidu.com/flondon/item/8c21c375723eff2fd7a89c95javascript

 

異步上傳文件並得到返回值(徹底跨域)

AJAX能夠進行數據的異步請求,但對於文件和跨域問題卻一籌莫展。php

Jsonp能夠進行跨域數據的異步請求,但一樣不能使用於文件。html

<form>表單能夠進行跨域數據和文件的上傳,但卻會使頁面跳轉。前端

那麼如何同時實現「異步」+「跨域」+「文件」+「返回值」這幾個特性呢?方法以下:java

原理:跨域

將<form>表單經過一個iframe來submit,也就是將<form>的target屬性設置爲一個iframe的id,這樣<form>的action URL就會在這個iframe中瀏覽器

打開,那麼服務器的返回數據也就會輸出到iframe中了。最後再經過主頁面也iframe之間的交互完成對返回數據的讀取(這涉及到跨域問題,服務器

文章後面將介紹此問題的解決方法)。dom

基本結構:異步

前端部分(當前域名: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傳輸的)。

相關文章
相關標籤/搜索