2015/10/28
【jQuery】IE9でページ遷移せずにファイルをPOSTしてJSONを受け取る
Ajaxを使ってフォームをPOSTすると、ページ遷移しないため、
管理画面などで連続して処理を行いたい場合、
こうすることでユーザのストレスを減らすことができます。
また、そのときのデータの受け渡しをJSONで行うことで、
HTMLの書き換えなどを柔軟に行うことができます。
フォームの種類にはいくつかありテキストボックスやチェックボックスなど、
ほとんどのフォーム要素は以下の様なコードを記述することにより、
Ajaxで問題なくPOSTを行うことができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $(function() { $("form").submit(function(event) { var $form = $(this); var $button = $form.find(":submit"); event.preventDefault(); $.ajax({ type: "post", url: "example.php", data: $form.serialize(), beforeSend: function(xhr, settings) { $button.attr("disabled", true); //二重送信を防止 }, }).done(function(json) { //成功したときの処理 }).fail(function(data, textStatus, errorThrown){ //失敗したときの処理 }).always(function(xhr, textStatus) { $button.attr("disabled", false); //二重送信を防止 }); }); }); |
↓こちらを参照
jQueryでフォームをAjax送信する際の基本パターンのチュートリアル。二重送信の防御とか。 | Ginpen.com
しかし、ファイルのフォームはこれでは送信できません。
AjaxでファイルのフォームをPOSTするには、
HTML5のfromData APIを利用する必要があります。
↓こちらを参照
[GNJYO!] AjaxでFormDataを使ってファイルアップロードする | GNJYOブログ
しかしながら、IE9はFormData APIに対応していません。
そのため、IE9においては、AjaxでファイルをPOSTすることができません。
IE9は対応を求められる機会が2015年時点ではまだ多いため、
対応を逃れるのは難しいのが現状です。
そんな中、↓こちらのサイトで、
iframeを利用することで、ページ遷移することなくファイルのフォームをPOSTする方法が、紹介されていましたので、紹介いたします。
Ajax的に画像などのファイルをアップロードする方法 ::ハブろぐ
↓作ってみたもの
(画像はダミーを表示するようにしています)
方法
手順は以下のとおり
- CSSで非表示にしたiframeを用意し、フォームのtargetをそのiframeに設定
- POSTされたデータを元に、プレーンテキストのJSONをPHPで出力し、iframeで受け取る
- iframeで受け取ったJSONの文字列をJSON.parse()で連想配列に変換
1. CSSで非表示にしたiframeを用意し、フォームのtargetをそのiframeに設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <form action="json-text.php" method="post" enctype="multipart/form-data" target="getJsonText" class="entry"> <table> <tr class="title"> <th class="required">画像タイトル</th> <td><input type="text" name="title" class="validate[required]"></td> </tr> <tr class="file"> <th class="required">画像ファイル</th> <td><input type="file" name="image"></td> </tr> </table> <p class="button"><input type="submit" value="確認する"></p> </form> <iframe class="hideIframe" name="getJsonText"></iframe> |
1 2 3 | .hideIframe { display: none; } |
form にtarget=”[iframeのname属性]” という風に属性を追加することで、
POSTの遷移先を次のページではなく、任意のiframeとして設定することができます。
iframeをCSSで隠してしまえば、POSTしている様子はユーザには見えません。
2. POSTされたデータを元に、プレーンテキストのJSONをPHPで出力し、iframeで受け取る
POSTされたPHPでJSONを吐き出しますが、通常のPOSTと異なり、
iframe内にJSONが読み込まれることになります。
その場合、通常のJSON形式だと、IEの場合、ファイルのダウロードとして認識されてしまい、
HTML上のデータとして扱うことができません。
そのため、この場合PHPで吐き出すJSONは、以下の様なヘッダーの設定を行い、
プレーンテキストの形式で出力します。
1 | <?php header('Content-type: text/plain; charset=utf-8'); ?> |
3. iframeで受け取ったJSONの文字列をJSON.parse()で連想配列に変換
1 2 3 4 5 6 7 8 9 10 11 | $(function() { $(document).on("submit", "form", function() { //iframeにPOSTで返ってきたページが表示されたら実行 $(".hideIframe").off().on("load", function() { var response = $(this).contents().find("pre").text(); //iframeに読み込んだテキストを取得 json = JSON.parse(response); //JSON形式に変換 $("tr.title td").text(json.title); $("tr.file td").html("<img src='" + json.image + "' width='120'>"); }); }); }); |
iframe内にJSONの内容を読み込むことができましたが、
このままではJSONデータではなく文字列のデータなので、
JSON.parse()を使って文字列からJSONデータに変換します。
これでIE9でもページ遷移なくファイルをPOSTし、JSONをサーバーから受け取ることができました。
参考にさせていただいたサイト
jQueryでフォームをAjax送信する際の基本パターンのチュートリアル。二重送信の防御とか。 | Ginpen.com
[GNJYO!] AjaxでFormDataを使ってファイルアップロードする | GNJYOブログ
Ajax的に画像などのファイルをアップロードする方法 ::ハブろぐ
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE