非同期ファイルアップロード(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になってるはずだからフィルタすればイケそうな気がしてきた。
  • 何かもっとスマートな方法はねぇのか!どっちにしろアタマ悪い感じ。