ファイルの非同期アップロードを実装してたら, 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のいずれかだったのですが, なぜかIEでJPEGをアップロードしても不正な形式扱い.
実装としてはMIMEタイプで見てたので, image/jpeg, image/gif, image/pngのいずれかだったら正しい形式と判断してたのですが, IEからJPEGをアップロードすると, MIMEタイプはimage/pjpeg…… pjpeg(・∀・`)?
なんか独自実装らしいです. 先生自由すぎ.
とりあえず許可するMIMEタイプにimage/pjpegを追加して事なきを得ました.
以上, 小学生のご報告でした.
*1:なぜわざわざフォームのコピーを作成してたかは謎