Home > 技術全般 > 画面遷移なしでファイルアップロードする方法

画面遷移なしでファイルアップロードする方法

画面遷移をせずに画像ファイルをアップロードさせたいと思った。
で、普通にAjaxでできるだろうと思ってコードを書き始めてハッと気付いた。
multipartで送るためにファイルを読もうとしても、Javascriptからじゃローカルのファイル読めないじゃん。(当たり前ですが、セキュリティのためにできなくなっています)

ということで以下のサイトにあるようにiframeを使う方法で実装した。
Rubyist - yamazのRails日記 - Ajaxっぽく画面遷移なしでファイルアップロードしたい! Railsで画面遷移なしでファイルアップロードを行うから引用

formタグにはtarget属性というのがあって,リクエストを処理するブラウザのウインドウ名が指定できます.
Aタグのtarget="_new"とかで新しいウィンドウを開くみたいなノリだ.
またそのターゲットはname指定されたiframeでもOKなので,iframe内で処理をすることによって遷移なしのファイルアップロードが実現できている.
今回の例では'frame'というname属性をもったダミーIframeタグを準備しているので,これがブラウザ上で見えて嫌な人はstyle="display:none;"などで隠すとよい.

RoRの話だとちょっと分かりにくい(単純に知らないともいう)ところがあったので、PHPで簡単なサンプルを作ってみた。
画像をアップロードすると、phpファイルが置かれているのと同じディレクトリに画像を保存して、フォームの下に画像が表示される(はず)。
※画像やファイル名のチェック、エラー処理などは全く考慮してないので注意!

upload_test.html
⇒ iframeのstyle=display:none;について注意が必要、追記参照

CODE:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.     <title>画面遷移なしでファイル(画像)アップロード</title>
  6. </head>
  7. <body>
  8.     <form action="./upload.php" method="post" enctype="multipart/form-data" target="upload_frame">
  9.         <input type="hidden" name="max_file_size" value="1000000" />
  10.         <input type="file" name="upload_image" />
  11.         <input type="submit" value="画像アップロード" />
  12.     </form>
  13.     <div id="container"></div>
  14.     <iframe name="upload_frame" style="display:none;"></iframe>
  15. </body>
  16. </html>

upload.php

CODE:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.     <title>画像アップロード(iframe内)</title>
  6. </head>
  7. <body>
  8. <?php
  9.     $upload_dir = './';
  10.     $filename = $_FILES['upload_image']['name'];
  11.     move_uploaded_file($_FILES['upload_image']['tmp_name'], $upload_dir.$filename);
  12. ?>
  13. <script type="text/javascript"><!--
  14.     var container = parent.document.getElementById('container');
  15.     image = parent.document.createElement('img');
  16.     image.src = './<?php print($filename);?>';
  17.     container.appendChild(image);
  18. //--></script>
  19. </body>
  20. </html>

ちなみにimgタグをcreateElementする際にparentを付け忘れると、Firefoxでは動くがIEでは動かないので注意。
(ちゃんと実装するときは親側に関数を用意してキックするほうがよいと思う)

これでファイルアップロードの時も、もう少しjavascriptをごにょごにょするといろんなことができそう。

※追記 2007/04/17 15:20
アップした直後によくまとまったサイトを見つけた。
画面遷移なしでファイルアップロードする方法 と Safariの注意点 (groundwalker.com)
どうやらSafariだとiframeのstyleにdisplay:none;を指定してはダメらしい。

iframe の style に display:none; を指定するサンプルコードを見かけるが Safari の場合 display:none; だとファイルアップロードのスクリプトが新しいウインドウで走ってしまうので注意。

気をつけなければ。

※追記 2007/07/18
このままでは、自分でアプリケーションを作ったときに上手く使えなかったので補足エントリーを書いた。
補足 画面遷移なしでファイルアップロードする方法

この方法は、画像をアップロードした瞬間に即座にデータを確定するときにはそのまま使えるが、画像とコメントなどを同時に編集して、次の画面でデータ確認やデータ登録完了させようとすると問題がある。
戻る対応をしていないので、確認画面や完了画面から戻るボタンで戻ると、アップロードした画像が消えてしまうから。

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://blog.joyfullife.jp/archives/2007/04/17134117.php/trackback
Listed below are links to weblogs that reference
画面遷移なしでファイルアップロードする方法 from 30からのBlog

Home > 技術全般 > 画面遷移なしでファイルアップロードする方法

Search
Feeds
Meta

Return to page top