2011年9月10日 星期六

Ruby on Rails multipart(上傳檔案) 讓 remote(ajax) 失效!

在 RoR 要 AJAX 來傳遞表單(form)非常的簡單,只需要把 form 的 remote 屬性設定成 true 就好。

<%= form_tag('/posts', :remote => true) %>
  # field here ...
<% end %>

 

而關於 AJAX event 的 handle,可以參考這篇

Rails 3 Remote Links and Forms: A Definitive Guide

 

 

但若要傳遞的是檔案就沒這麼簡單了,因為 form 的 multipart 屬性會讓 remote 失效!

<%= form_tag('/posts', :remote => true, :multipart => true) %>
  # field here ...
<% end %>

 

這並不是  RoR 的問題,而是 Javascript 本來就無法存取本機得資源,若要達成還是得利用 iframe 來讓瀏覽器幫忙將檔案送到 server 端而不重新讀取頁面,以 php 為例,你必須這樣做。

index.php

<form id="upload_form" method="post" enctype="multipart/form-data" action="upload.php">
    <input name="file" id="file" type="file"/>
    <input type="submit" name="action" value="Upload"/>
    <iframe id="upload_iframe" name="upload_iframe" style="width: 500px; height: 500px; border: 1px solid #000;"></iframe>
</form>
 
<script>
function init() {
    document.getElementById('upload_form').onsubmit=function() {
        document.getElementById('upload_form').target = 'upload_iframe';
    }
}
window.onload=init;
</script>

 

upload.php

<pre>
<?
    // 處理一般 upload 的程式碼放這,這邊只印出 $_FILES 的內容
    print_r($_FILES);
?>
</pre>
 
<script>
// 還是可以呼叫到前一個頁面的元素進行互動
alert(parent.document.getElementById('upload_form'));
</script>

 

在 RoR 世界裡,已經有人把他寫成套件了,或許安裝有點繁瑣,使用起來也不是那麼的順手,但基本上還是維持了 RoR 的一致性,可以參考看看底下這個 solution。(裡面已有安裝教學以及使用範例)

https://github.com/leppert/remotipart

2 則留言: