強敵Firefox
input type="file"のonchangeでファイルを勝手にアップロードしてプレビューをひっぱってくる仕掛けを作ろうとしてたんだが・・・
<form action="登録するとこ"> <input type="file" name="hoge" id="hoge"> </form> ... <form action="あっぷろーだ"> <input type="file" name="piyo" id="piyo"> </form> ... <script じゃばすくりぷと> Event.observe('hoge','change',function( evt ){ $('piyo').value=$('hoge').value; }); </script>
というJavascriptコードを書くとFirefoxでセキュリティエラーで蹴られる。
すなわちtype=fileの要素にDOMでvalueは書いちゃいけないって事だ。
まぁたしかにこれが通ると、いろいろ悪さできるしなぁ・・・
-
-
- -
-
でも困った(´・ω・`)
非同期ファイルアップロード(not ajax)の検討
先の件をとりあえず解決法。
- input type="file"がコピーできねぇならフォームのターゲットとアクションを差し替えちゃえ!
- 終わったら元のactionに戻す(イベントドリブンだから2つ走ったらぐちゃぐちゃになる気はする)
- name="hoge"を本当のPOST先につっこみたい。これすなわちアップロードが終わってるファイルのファイルパス
- prototype.js前提(適当にjs書き換えれば無しでもいけると思うが)
- バリデータとかは適当に
<form action="本番POST" id="hoge_form" method="post" enctype="multipart/form-data" > <iframe "target_iframe"></iframe> <input type="file" name="dummy" id="dummy_input" /> <input type="hidden" name="hoge" /> </form> <script language="JavaScript" type="text/javascript"> Event.observe('dummy_input','change',function( evt ){ var backup_action = $('hoge_form').action; $('hoge_form').target="target_iframe"; // 放り込むターゲットiframeを指定する $('hoge_form').action="upload_action.php"; // ファイルアップロードを受け付けるサーバスクリプト $('hoge_form').submit(); // つっこめー $('hoge_form').action=backup_action; // とりあえず元に戻す $('hoge_form').target=null; // ターゲットは消しとく( } </script>
- 呼ばれる方(upload_action.php)
<? define(PUBLIC_PATH,"/home/ore/public_html/tmp_image"); define(PUBLIC_HOME,"http://ore.com/tmp_image"); $public_tmp_filepath=move_tmp2publicTmp( $_POST['dummy'] ); /** * $form_varの['type']見て拡張子判別して、拡張子抜いたテンポラリ名を作る * */ function move_tmp2publicTmp( $form_var ){ switch($form_var['type']) { case 'image/gif': $dst_filename=basename_noext($form_var['tmp_name']).".gif"; break; case 'image/jpeg': case 'image/jpg': $dst_filename=basename_noext($form_var['tmp_name']).".jpg"; break; case 'image/png': $dst_filename=basename_noext($form_var['tmp_name']).".png"; break; } //PHPテンポラリから表示用テンポラリ領域へ移動 move_uploaded_file($form_var['tmp_name'] ,PUBLIC_PATH.$dst_filename); return PUBLIC_HOME.$dst_filename; } ?> <ここいらhtmlとかheaderとかbodyとか適当に> <img src="<? $public_tmp_filepath ?>"> <script language="JavaScript" type="text/javascript"> // iframeの中だからparentからhiddenを探して値を突っ込む window.parent.document.getElementById('hoge').value='<? $public_tmp_filepath ?>'; // ↑parent.document.$('hoge').valueでいいんじゃないかこれ? </script>
ここまで書いたが重大な問題
- input type="file"がフォーム内で1個ならともかく、複数あると全部Uploadしやがるのでフォームはやっぱ分けないとだめじゃんorz
- div内のinput全部ひろってきてsubmit()する何かを書くか・・・(´Д`;
- input type="file"はUp済みのファイル名が入ったhiddenになってるはずだからフィルタすればイケそうな気がしてきた。
- 何かもっとスマートな方法はねぇのか!どっちにしろアタマ悪い感じ。