jQuery.ajax()でファイルをアップロードする方法

jQuery.ajax()でファイルをアップロードする方法

Posted at September 30,2014 1:33 AM
Tag:[Ajax, jQuery]

jQuery.ajax()でファイルをアップロードする方法を紹介します。

1.はじめに

jQuery.ajax()で画像ファイルをサーバに送信し、バックエンドのPHPで画像の幅・高さを返却し、それを表示するという簡単なプログラムを組んでみました。

フロントエンド

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
$(function(){
    $('#foo').submit(function(){
        $.ajax({
            url: "test.php",
            type: 'POST',
            data: {
                'file': $('#file').val()
            },
            dataType: 'json'
        })
        .done(function( data ) {
            $('#result').text(data.width + "x" + data.height);
        });
        return false;
    });
});
</script>
<form id="foo">
    <input id="file" name="file" type="file" />
    <input id="send" type="submit" />
</form>
<div id="result"></div>

バックエンド

<?php
if ($_FILES['file']) {
    $size = getimagesize( $_FILES['file']['tmp_name'] );
    $data = array( 'width' => $size[0],
                   'height' => $size[1] );
    header('Content-type: text/html');
    echo json_encode($data);
}
?>

が、このプログラムではtype="file"で送信するデータがファイル名(文字列)になってしまい、正常に動作しません。

2.jQuery.ajax()でファイルをアップロードする

jQuery.ajax()でファイルをアップロードするにはscript要素部分を赤色部分のように変更する必要があります。

<script>
$(function(){
    $('#foo').submit(function(){
        var fd = new FormData($('#foo').get(0));
        $.ajax({
            url: "test.php",
            type: "POST",
            data: fd,
            processData: false,
            contentType: false,
            dataType: 'json'
        })
        .done(function( data ) {
            $('#result').text(data.width + "x" + data.height);
        });
        return false;
    });
});
</script>

まず、type="file"を含むinput要素は、FormDataオブジェクトで取得します(個別に取得する方法もありますがここでは割愛)。FormDataオブジェクトは、XMLHttpRequestを使用して送信するためのキーと値のセットを収集可能にするためのものです。

        var fd = new FormData($('#foo').get(0));

そしてdata:にはFormDataオブジェクトを設定します。

            data: fd,

なお、FormDataオブジェクトはIE9・Android2.3より前のバージョンでは使えないようです。

そしてprocessData:とcontentType:をfalseにします。

            processData: false,
            contentType: false,

processDataは、data:に指定したオブジェクトをGETメソッドのクエリ文字への変換有無を設定する項目で、ファイルを送信する場合にはPOSTメソッドのまま送信する必要があるため、必ずfalseを設定します。

contentType:はデータ送信時のcontent-typeヘッダの値になりますが、FormDataオブジェクトの場合は適切なcontentTypeが設定されるので、同じくfalseを設定します。

余談ですが、このサンプルではsubmit()の返却値をfalseにして、本来のsubmit動作を行わないようにしています。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)