FormData クラスは、クライアント側でフォームデータを構築・送信するための便利なツールです。
特に、画像やファイルなどのバイナリデータをサーバーに送信する際に広く使用されます。
以下で FormData の基本的な使い方や具体例を詳しく解説します。
基本構文
FormData インスタンスの作成
javascriptconst formData = new FormData();
データの追加
データを append メソッドで追加します。
javascriptformData.append("key", "value"); // キーと値のペアを追加
key: サーバー側で使用するキー名。value: 送信するデータ。文字列、ファイルオブジェクト、Blobなどが使用できます。
送信したいデータをまとめて ”ポイ” です。
その入れ物がformDataクラスです。だらだらコードをbodyに記述するより、スッキリします。
データの送信
通常は fetch または axios を使ってサーバーに送信します。
javascriptコードをコピーするfetch('http://example.com/api/upload', {
method: 'POST',
body: formData,
});
使用例
以下は、React+TypeScriptで画像をアップロードする例です。
画像アップロードのコード例
tsximport React, { useState } from "react";
const ImageUploader: React.FC = () => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files && event.target.files.length > 0) {
setSelectedFile(event.target.files[0]); // ファイルオブジェクトを保存
}
};
const handleUpload = async () => {
if (!selectedFile) {
alert("画像を選択してください!");
return;
}
// FormDataの作成
const formData = new FormData();
formData.append("image", selectedFile); // "image" はサーバーで受け取るキー名
try {
const response = await fetch("http://localhost:8000/api/upload", {
method: "POST",
body: formData, // FormDataを送信
});
if (response.ok) {
const result = await response.json();
console.log("アップロード成功:", result);
} else {
console.error("アップロード失敗:", response.statusText);
}
} catch (error) {
console.error("エラーが発生しました:", error);
}
};
return (
<div>
<h1>画像アップロード</h1>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>アップロード</button>
</div>
);
};
export default ImageUploader;
FormDataの主要メソッド
1. append
データを追加します(キーが重複した場合、値が追加される)。
javascriptformData.append("key", "value"); // キーと値を追加
formData.append("file", fileObject); // ファイルを追加
2. set
データを追加または更新します(キーが重複した場合、値を上書きする)。
javascriptformData.set("key", "newValue"); // キーが存在すれば更新、存在しなければ追加
3. delete
特定のキーを削除します。
javascriptformData.delete("key");
4. has
指定したキーが存在するかを確認します。
javascriptconsole.log(formData.has("key")); // 存在すれば true, 存在しなければ false
5. get
指定したキーに対応する値を取得します。
javascriptconsole.log(formData.get("key")); // キーに対応する値を取得
6. entries
キーと値のペアを Iterator として取得します。
javascriptfor (let [key, value] of formData.entries()) {
console.log(key, value);
}
ファイル送信時の注意点
1. Content-Typeヘッダーを指定しない
FormData を送信する場合、Content-Type ヘッダーを指定する必要はありません。
ブラウザが自動的に適切な Content-Type(例: multipart/form-data)を設定します。
javascriptfetch("http://example.com/upload", {
method: "POST",
body: formData, // Content-Typeはブラウザが設定
});
もし手動で Content-Type を設定すると、FormData が正しく送信されない可能性があります。
2. CORSの許可
サーバーが異なるオリジンの場合、CORSの設定が必要です。
サーバー側で以下のように設定します。
Laravelの場合(config/cors.php)
phpreturn [
'paths' => ['api/*'],
'allowed_methods' => ['POST'],
'allowed_origins' => ['http://localhost:3000'], // ReactアプリのURL
'allowed_headers' => ['Content-Type', 'Authorization'],
'supports_credentials' => false,
];
基本的にデフォルトでは、全てを受け入れる構成となっています。
// cors.php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
3. ファイルのバリデーション
画像を送信する際、ファイルサイズや形式をサーバーまたはクライアントで検証します。
クライアント側の例(React)
tsxconst handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
if (file.size > 2 * 1024 * 1024) { // 2MBを超える場合
alert("ファイルサイズが大きすぎます。2MB以下のファイルを選択してください。");
return;
}
if (!["image/jpeg", "image/png"].includes(file.type)) {
alert("JPEGまたはPNG形式の画像を選択してください。");
return;
}
setSelectedFile(file);
}
};
まとめ
FormData は、特にファイルアップロードに便利で、キーと値のペアを直感的に扱える
強力なツールです。
適切な検証やサーバーの設定を行えば、簡単にファイルを安全に送信することができます。
主な特徴
- 複雑なデータ構造でも簡単に扱える。
- 自動的に
Content-Typeを設定。 - ファイルやBlobを扱える。
これを活用して、効率的なアップロード機能を実装してみてください!
上記の
formData.append(“image”, selectedFile);のselectedFileですが、
通常は <input type="file"> フィールドに紐づけします。
ReactなのでsetSelectedFileを使いユーザーがファイルを選択した際に
取得される File オブジェクトを代入します。
具体的には、<input> フィールドの onChange イベントを介して、File オブジェクトを取得し、それを FormData に追加します。
Fileオブジェクトとは、
具体的な仕組み
1. <input> と selectedFile の紐付け
<input type="file"> は、ユーザーが選択したファイルを event.target.files から取得します。
これにより、selectedFile に実際のファイルオブジェクトが格納されます。
サンプルコード
以下のコードで、selectedFile に選択されたファイルを紐づける様子を説明します:
tsximport React, { useState } from "react";
const FileUpload: React.FC = () => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
// ファイル選択時に呼び出される関数
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
// ファイル選択時、ファイルを `selectedFile` に格納
if (event.target.files && event.target.files.length > 0) {
setSelectedFile(event.target.files[0]); // 最初のファイルを取得
}
};
const handleUpload = () => {
if (!selectedFile) {
alert("ファイルを選択してください!");
return;
}
// FormDataにファイルを追加
const formData = new FormData();
formData.append("image", selectedFile); // "image" はサーバーで受け取るキー名
// デバッグ: FormDataの中身を確認
for (let [key, value] of formData.entries()) {
console.log(key, value); // キーと値を出力
}
// 送信処理 (例: fetch または axios)
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload}>アップロード</button>
</div>
);
};
export default FileUpload;
動作の流れ
- ユーザーがファイルを選択する:
<input type="file">フィールドでユーザーがファイルを選択。- 選択されたファイルは
event.target.files[0]に格納される。 setSelectedFileを通じてselectedFileにセットされる。
FormDataに追加する:formData.append("image", selectedFile)によって、
選択されたファイルが “image” というキー名で追加される。
- サーバーに送信:
fetchやaxiosを使用してサーバーに送信。- サーバーでは、”image” というキー名でアップロードされたファイルを取得。
重要な点
複数ファイルの場合:<input> フィールドで multiple 属性を使用すると、複数ファイルを選択できます。
その場合、event.target.files は FileList 型になり、ループで各ファイルを
取得できます。
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
for (const file of event.target.files) {
formData.append("images[]", file); // 配列形式で追加
}
}
};
サーバー側のキー名に一致させる:formData.append("image", selectedFile) の "image" というキー名は、サーバー側で設定されているフィールド名と一致する必要があります。
ファイル検証:
クライアント側でファイル形式やサイズを検証できます(例: JPEG/PNG形式、2MB以下など)。
tsx
if (selectedFile) {
if (selectedFile.size > 2 * 1024 * 1024) {
alert("ファイルサイズが2MBを超えています");
return;
}
if (!["image/jpeg", "image/png"].includes(selectedFile.type)) {
alert("JPEGまたはPNG形式のみ対応しています");
return;
}
}
まとめ
formData.append("image", selectedFile) の selectedFile は、
ユーザーが <input type="file"> フィールドを通じて選択したファイルとします。
このファイルは onChange イベントで取得され、File オブジェクトとして selectedFile に格納されます。
これを FormData に追加することで、サーバーに画像を送信できます。
正しく紐付けるためには以下を確認してください:
<input type="file" onChange={handleFileChange} />を使う。event.target.filesからFileオブジェクトを取得する。formData.append()で適切に追加する。



