Jump to the content

Ajaxを使わずに画面遷移なしで画像ファイルをアップロード(IE9対応版)

JavaScript

    今日は画像ファイルのアップロードを実装する方法のご紹介です。 ファイルアップロード時の画面遷移はしないケースで考えます。1ページ完結型です。 Ajaxは使わず、シンプルに通常のフォーム送信で実装します。

    やり方

    ファイル送信自体にはフォーム要素を使います。

    <form id="FileUpload" name="upload" method="post" action="/api/upload" target="upload-image" enctype="multipart/form-data">
        <input type="file" name="image" />
        <input type="submit" name="submit" value="送信" />
    </form>
    
    <iframe id="FileUploadIframe" name="upload-image" style="display: none;"></iframe>
    

    ここで重要なのは、非表示のiframeを配置することと、 フォーム要素のtarget属性値にiframeのname属性を指定して、iframeにフォームでのやりとりを任せてしまうことです。

    これで普通にフォーム送信をして、サーバからはレスポンスとしてHTMLを返してもらいます。 JSONを返してもらいたい場合はiframeからJSONを受け取れるようにscriptタグの中でメソッドを定義してその中に格納してしまいましょう。

    <!-- サーバが返すHTML -->
    
    <!DOCTYPE html>
    <html lang="ja">
        <head>
            <meta charset="UTF-8">
        </head>
        <body>
            <script>
                // iframeの中で呼ばれるのでwindow.parentで親フレームからアクセスできるようにする
                window.parent &&
                window.parent.Global &&
                window.parent.Global.sendJSON &&
                window.parent.Global.sendJSON({
                    "meta": {
                        "code": 200,
                        "status":"success"
                    },
                    "content": {
                        "id": "*********"
                    }
                });
            </script>
        </body>
    </html>
    

    イメージとしてはJSONPに近いですね。

    返り値の処理はあらかじめwindow.Global.sendJSONというメソッドをグローバルに用意しておきます。

    window.Global.sendJSON = function(data) {
    
        var response = data.content;
    
        if (data.meta.status === 'success') {
            // 通信成功時の処理
        } else {
            // 通信失敗時の処理
        }
    
    };
    

    サーバからレスポンスがない場合を想定してタイムアウトを設定しておくとより親切です。 アップロードに時間がかかることも考慮すると、ファイルサイズの上限を決めてしまうのもアリだと思います。

    ファイルプレビューを表示したい

    FileAPIを使うと簡単に実装できます。(注:IE10以上対応

    HTML

    <form id="FileUpload" name="upload" method="post" action="/api/upload" target="upload-image" enctype="multipart/form-data">
        <input type="file" name="image" />
        <input type="submit" name="submit" value="送信" />
    </form>
    
    <iframe id="FileUploadIframe" name="upload-image" style="display: none;"></iframe>
    
    <!-- プレビュー挿入用の要素を用意する -->
    <div id="FileUploadPreview"></div>
    

    Javascript

    var form = document.forms.upload,
        input = form.input,
        submit = form.submit,
        preview = doc.getElementById('FileUploadPreview');
    
    function preview(file) {
        if (file.type.match(/image/)) {
            var fr = new FileReader();
    
            fr.onload = function(e) {
                var img = new Image();
                img.src = e.target.result;
                preview.innerHTML = '';
                preview.appendChild(img);
            };
            fr.readAsDataURL(file);
        }
    }
    
    if (!window.File) {
        return;
    } else {
        submit.addEventListener('click', function(e) {
            var file = input.files[0];
            preview(file);
        }, false);
    }
    
    

    IE9以下もサポートする場合は、フォーム送信時にサーバからプレビュー用画像を返してもらい表示しましょう。

    注目記事

    最近の記事

    ぼくが書いてます

    フロントエンドエンジニア

    イソップ

    ページの先頭に戻る

    Search results

    ×