JavaScript/FormData

FormDataオブジェクト

概要

FormDataオブジェクトはHTMLフォームのデータを簡単に取り扱うためのJavaScriptオブジェクトです。このオブジェクトを使用すると、フォームのデータを収集して送信する際の作業が大幅に簡略化されます。特にAjaxリクエストでのファイルアップロードを含むフォーム送信に非常に便利です。

FormDataオブジェクトの作成

FormDataオブジェクトは、空のインスタンスを作成するか、既存のフォーム要素からデータを取得して作成することができます。

// 空の<code>[[../FormData|FormData]]</code>オブジェクトを作成
const emptyFormData = new FormData();

// HTMLのform要素から<code>[[../FormData|FormData]]</code>オブジェクトを作成
const form = document.querySelector('#myForm');
const formData = new FormData(form);

主なメソッド

FormDataオブジェクトには、データの操作に役立つ様々なメソッドが用意されています。

const formData = new FormData();

// データの追加
formData.append('username', 'tanaka');
formData.append('email', 'tanaka@example.com');

// ファイルの追加
const fileInput = document.querySelector('#fileInput');
formData.append('profileImage', fileInput.files[0]);

// 同じキーに複数の値を追加
formData.append('interests', '読書');
formData.append('interests', '旅行');

// 値の設定(同じキーの既存値を上書き)
formData.set('username', 'suzuki');

// 値の取得
const username = formData.get('username'); // 'suzuki'
const interests = formData.getAll('interests'); // ['読書', '旅行']

// 値の存在確認
const hasEmail = formData.has('email'); // true

// 値の削除
formData.delete('email');

// すべてのキーを取得
const keys = formData.keys(); // Iterator

// すべての値を取得
const values = formData.values(); // Iterator

// すべてのキーと値のペアを取得
const entries = formData.entries(); // Iterator

FormDataとフェッチAPIの連携

FormDataオブジェクトはフェッチAPIと組み合わせることで、簡単にフォームデータをサーバーに送信できます。

const form = document.querySelector('#signupForm');

form.addEventListener('submit', async (event) => {
    event.preventDefault();
    
    const formData = new FormData(form);
    
    try {
        const response = await fetch('/api/signup', {
            method: 'POST',
            body: formData
            // Content-Typeヘッダーは自動的に設定されるため不要
        });
        
        if (response.ok) {
            const result = await response.json();
            console.log('登録成功:', result);
        } else {
            console.error('登録失敗:', response.statusText);
        }
    } catch (error) {
        console.error('エラー発生:', error);
    }
});

ファイルアップロード

FormDataオブジェクトを使用したファイルアップロードの実装例です。

const uploadForm = document.querySelector('#uploadForm');
const progressBar = document.querySelector('#progressBar');
const statusMessage = document.querySelector('#statusMessage');

uploadForm.addEventListener('submit', async (event) => {
    event.preventDefault();
    
    const formData = new FormData(uploadForm);
    const xhr = new XMLHttpRequest();
    
    xhr.open('POST', '/api/upload', true);
    
    xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
            const percentComplete = (event.loaded / event.total) * 100;
            progressBar.value = percentComplete;
            statusMessage.textContent = `アップロード中: ${Math.round(percentComplete)}%`;
        }
    });
    
    xhr.addEventListener('load', () => {
        if (xhr.status === 200) {
            statusMessage.textContent = 'アップロード完了';
        } else {
            statusMessage.textContent = `エラー: ${xhr.statusText}`;
        }
    });
    
    xhr.addEventListener('error', () => {
        statusMessage.textContent = 'アップロード中にエラーが発生しました';
    });
    
    xhr.send(formData);
});

FormDataオブジェクトとJSONの相互変換

FormDataオブジェクトのデータをJSON形式に変換したり、JSONからFormDataオブジェクトを作成したりする例です。

// FormDataからJSONオブジェクトへの変換
function formDataToJson(formData) {
    const json = {};
    
    for (const [key, value] of formData.entries()) {
        if (json[key]) {
            if (!Array.isArray(json[key])) {
                json[key] = [json[key]];
            }
            json[key].push(value);
        } else {
            json[key] = value;
        }
    }
    
    return json;
}

// JSONオブジェクトからFormDataへの変換
function jsonToFormData(json) {
    const formData = new FormData();
    
    for (const key in json) {
        if (Array.isArray(json[key])) {
            json[key].forEach(value => {
                formData.append(key, value);
            });
        } else {
            formData.append(key, json[key]);
        }
    }
    
    return formData;
}

ブラウザ互換性

FormDataオブジェクトは主要なブラウザで広くサポートされています。

ブラウザ バージョン
Chrome 7以上
Firefox 4以上
Safari 5以上
Edge 12以上
IE 10以上
Opera 12以上

実践的な使用例:動的フォーム要素の追加

FormDataオブジェクトを使用して、動的に追加されたフォーム要素のデータを送信する例です。

const dynamicForm = document.querySelector('#dynamicForm');
const addFieldButton = document.querySelector('#addField');
const fieldsContainer = document.querySelector('#fieldsContainer');
let fieldCount = 0;

addFieldButton.addEventListener('click', () => {
    fieldCount++;
    
    const fieldDiv = document.createElement('div');
    fieldDiv.className = 'form-field';
    fieldDiv.innerHTML = `
        <label for="field${fieldCount}">項目 ${fieldCount}:</label>
        <input type="text" id="field${fieldCount}" name="field${fieldCount}">
        <button type="button" class="remove-field">削除</button>
    `;
    
    fieldsContainer.appendChild(fieldDiv);
    
    fieldDiv.querySelector('.remove-field').addEventListener('click', () => {
        fieldDiv.remove();
    });
});

dynamicForm.addEventListener('submit', async (event) => {
    event.preventDefault();
    
    const formData = new FormData(dynamicForm);
    
    // カスタムデータの追加
    formData.append('fieldCount', fieldCount.toString());
    formData.append('submitTime', new Date().toISOString());
    
    console.log('送信データ:');
    for (const [key, value] of formData.entries()) {
        console.log(`${key}: ${value}`);
    }
    
    // 実際のデータ送信処理
    try {
        const response = await fetch('/api/submit-dynamic', {
            method: 'POST',
            body: formData
        });
        
        const result = await response.json();
        console.log('送信結果:', result);
    } catch (error) {
        console.error('送信エラー:', error);
    }
});

FormDataオブジェクトは、フォームデータの取り扱いを簡素化し、特にファイルアップロードなどの複雑な処理を簡単に実装できるようにする強力なツールです。モダンなWeb開発において、フォーム送信の際に積極的に活用することをお勧めします。

附録

静的プロパティ

FormData.arguments
FormData.caller
FormData.length
FormData.name
FormData.prototype

静的アクセサ

静的メソッド

継承関係

ObjectFormData

FormDataのインスタンスプロパティ

FormData.prototype [ Symbol.toStringTag ]

FormDataのインスタンスアクセサ

FormDataのインスタンスメソッド

FormData.prototype.append()
FormData.prototype.constructor()
FormData.prototype.delete()
FormData.prototype.entries()
FormData.prototype.forEach()
FormData.prototype.get()
FormData.prototype.getAll()
FormData.prototype.has()
FormData.prototype.keys()
FormData.prototype.set()
FormData.prototype.values()
FormData.prototype [ Symbol.iterator ] ()
カテゴリ:JavaScript
カテゴリ:JavaScript