2006-09-08RailsでAjaxっぽく画面遷移なしでファイルアップロードしたい!

「RailsでAjaxっぽく画面遷移なしでファイルアップロードしたい!」
と思っていたところ,こんなページが見つかった.
http://sean.treadway.info/demo/upload/
であれこれ解析していたところ,のりおさん@RailsChatからナイスなモノを教えてもらった(同じサイトなのに気づかなかった).
http://sean.treadway.info/svn/plugins/responds_to_parent/
https://github.com/markcatley/responds_to_parent
結果として画面遷移なしでファイルのアップロードができるようになった.
ついでにざっと解析したので使い方と解析結果を備忘録もかねて書いておく(最近このパターンばっかし).
使い方
1. respond_to_parent pluginをインストール
% ruby script/plugin install https://github.com/markcatley/responds_to_parent.git
<div id="stuff">Here is some stuff</div>
<form target="frame" action="form_action" enctype="multipart/form-data" method="post">
<input type="file" name="uploaded_file"/>
<input type="submit"/>
</form>
<iframe id='frame' name="frame"></iframe> <!-- ← Upload用ダミーIframe -->
3. contoroller(のメイン部分)はこんなの
def main
end
def form_action
# Do stuff with params[:uploaded_file]
file = params[:uploaded_file]
File.open("/tmp/#{file.original_filename}","wb") do |f|
f.write(file.read)
end
responds_to_parent do
render :update do |page|
page << "alert($('stuff').innerHTML)"
end
end
end
これで/tmpにファイルが遷移なしでアップロードされます.
今回RJSでprototype.js使ってますが,本来はprototype.jsは必須ではないです.
仕組み
JavaScriptではファイルアップロードできません
まずJavaScript単体ではファイルのアップロードはできません.
AjaxはFormデータをシリアライズしてサーバにリクエストを投げていますが,
ファイルのアップロードができちゃうとJavaScriptがPCのファイルを
のぞけると言うことになっちゃうので,セキュリティ上できません.
formのtarget属性を使ってiframe内でactionのリクエスト結果を表示する
formタグにはtarget属性というのがあって,リクエストを処理するブラウザの
ウインドウ名が指定できます.Aタグのtarget="_new"とかで新しいウィンドウを
開くみたいなノリだ.またそのターゲットはname指定されたiframeでもOKなので,
iframe内で処理をすることによって遷移なしのファイルアップロードが実現できている.
今回の例では'frame'というname属性をもったダミーIframeタグを準備しているので,
これがブラウザ上で見えて嫌な人はstyle="display:none;"などで隠すとよい.
iframe側では親Windowの情報を取得できる.
またiframe側では親Window(Iframeタグが書かれたページ)の情報も取得,JSによるDOM書き換えができる.
それをサポートしてくれるのがresponds_to_parentで、ブロック内でrender :updateすると呼び出し側のページに対して動作するようなJSコードをIframe内に展開&評価実行する.これによってアップロードした後にページを書き換えたいなどもOKになる.あとブロックを持つことでRJSも書ける.
はまりどころ
付属のREADMEのFORMタグにはenctype="multipart/form-data" method="post"がついてないのでつけましょう.
使ってみた感想
これで画面遷移なしでファイルのアップロードができるようになった.
これを利用すればファイルをアップロードした後にその画像をいきなり表示とかも可能なので,
かっちょいいページをゼヒ作っていきたい.
(おしまい)
yamaz的日常
はてな近藤さんがアメリカ行った理由ってアメリカ出張で「東京での通勤イヤイヤ病」にかかったからだと思う(だいたひかる調).
9/10追記
上記responds_to_parent pluginですが,ブラウザの不具合でJavaScriptを含むHTML
(正確には</script>を含むHTML)を親ページにレンダリングしようとすると
うまく動かないようだったので,パッチを送って採用してもらいました.
万一すでにインストールした人がいたら再インストールするといいです.
Kathreen2011/09/08 12:37You're a real deep thikner. Thanks for sharing.
glviiiwudmu2011/09/09 00:0048VA3A <a href="http://uchnwlgzldpe.com/">uchnwlgzldpe</a>
grtcrfqu2011/09/09 21:25FGTAmK , [url=http://hnvoauohhlhf.com/]hnvoauohhlhf[/url], [link=http://dbbkalfnydpt.com/]dbbkalfnydpt[/link], http://pwlaogiwsejv.com/
ednkvcowipw2011/09/10 19:28EYACJZ <a href="http://cxcthullvckd.com/">cxcthullvckd</a>
rwnwso2011/09/12 19:36dYvsBV , [url=http://eshrsonsdhpq.com/]eshrsonsdhpq[/url], [link=http://habmzmsjzeql.com/]habmzmsjzeql[/link], http://rpcpiaehihqt.com/
- http://d.hatena.ne.jp/technohippy/20070515
- gmailで添付ファイルが自動でアップロードされ...
- http://d.hatena.ne.jp/bellx2/20070912
- http://d.hatena.ne.jp/onozaty/20070921
- lasの日記 - ShootingStarで画像投稿掲示版を作る(...
- akimatter - Ajaxっぽいファイルアップロード
- cuspos diary - ファイルアップロードをAJAX風に
- cuspos diary - ファイルアップロードをAJAX風に
- ファイルアップロードをajax風に実現する