ファイルの非同期アップロードを実装してたら, IEでいっぱい怒られたよ

すげー怒られたので, 逆ギレのごとくここにご報告いたします. 気分は先生に怒られた小学生.

「同一ドメインなのにiframeのdocumentを取得出来ませんよ!?」「うっせーなー」

非同期アップロードはform要素のtarget属性を任意のインラインフレームにして実装するのが定石だと思います. なので結果は指定したインラインフレームの中にあるため, documentを取得しないと結果がわかりません. ちなみに取得方法は:

var iframe = document.getElementById('iframe-id');

iframe.onreadystatechange = function() { // IEはiframe要素でloadイベントが発生しないらしい(IE8だと普通に発生してたけど)
  if (iframe.readyState == 'complete') {
    var doc = iframe.contentWindow.document; // contentWindowを経由して取得
  }
};

でしょうか. IE8で試してたので, contentDocumentもありましたが.

当然異なるドメインであれば, Same origin policyが適用され, アクセスが拒否されるのですが, 同じドメインでもアクセスが拒否されました.

で, どうやらレスポンスのステータスコードが200以外だと, documentプロパティを参照したときに「アクセスが拒否されました」と言われるようです. エラーならステータスコードを適切な内容にしたいのですが, それは許されないようですね. 先生厳しすぎ.

とりあえず回避するにはステータスコードを200にしなければいけないので:

status 200

って書いておきました. あ, サーバー側にはSinatra使ってたので.

「アップロードするファイルが選択されていませんよ!?」「あー, だりぃ」

アップロードするファイルを選択するためには, <input type="file" />を設けなければいけません. で, 問題なのはコイツのvalue属性. どうやらJavaScriptから設定するコトが出来ず, 閲覧者の操作によってでしか設定出来ないようです. 先生頭固すぎ.

実装としては元々あるフォームをコピーしてたのですが, そんなコトする必要もないと思い, 元々あるそのフォームのtarget属性をインラインフレームにして対処しました*1.

「アップロードしたファイルがJPEGじゃありませんよ!?」「帰りたーい」

アップロードできるファイルはJPEG, GIF, PNGのいずれかだったのですが, なぜかIEJPEGをアップロードしても不正な形式扱い.

実装としてはMIMEタイプで見てたので, image/jpeg, image/gif, image/pngのいずれかだったら正しい形式と判断してたのですが, IEからJPEGをアップロードすると, MIMEタイプはimage/pjpeg…… pjpeg(・∀・`)?

なんか独自実装らしいです. 先生自由すぎ.

とりあえず許可するMIMEタイプにimage/pjpegを追加して事なきを得ました.

以上, 小学生のご報告でした.

*1:なぜわざわざフォームのコピーを作成してたかは謎