multipart/form-data境界解説
multipart/form-dataの境界について(日本語)
multipart/form-dataは、HTTPリクエストのボディ内で複数の異なるデータ型を同時に送信するためのエンコーディング形式です。これは主に、HTMLフォームからのファイルアップロードや、複数の異なるデータ型を同時に送信する必要がある場合に使用されます。
境界(Boundary)とは?
境界は、multipart/form-dataの各パートを区切るための特殊な文字列です。この文字列は、フォーム送信時にサーバーによって生成され、リクエストのヘッダに設定されます。
境界の役割
- データ型の指定
各パートのヘッダには、そのパートのデータ型(例えば、text/plain
、image/jpeg
など)が指定されます。これにより、サーバーは各パートのデータを適切に処理することができます。 - パートの区別
境界は、各パートの開始と終了を明確に示すことで、サーバーが異なるパートを正確に識別できるようにします。
境界の構文
境界は、ダッシュ(-)とハイフン(-)で囲まれた任意の文字列です。例えば、--boundary1234567890
という境界を使用することができます。
multipart/form-dataの構造
--boundary
Content-Disposition: form-data; name="field1"
value1
--boundary
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
<binary data of the image>
--boundary--
- --boundary--
境界の終了を示します。 - <binary data>
パートのデータ内容です。 - Content-Type
パートのデータ型を指定します。 - filename
ファイルのパートの場合はファイル名を指定します。 - name
パートの名前を指定します。 - Content-Disposition
パートの情報を指定します。
境界の処理
サーバーは、受信したmultipart/form-dataリクエストの境界を解析し、各パートを抽出して処理します。各パートのデータ型に基づいて、適切な処理が行われます。例えば、ファイルのパートはサーバーにアップロードされ、テキストのパートはデータベースに保存されるなどです。
--boundary
Content-Disposition: form-data; name="field1"
value1
--boundary
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
<binary data of the image>
--boundary--
コード例(サーバー側)
PHP
<?php
// multipart/form-dataの処理
$boundary = "--boundary1234567890"; // 実際にはサーバーによって生成される
$data = file_get_contents('php://input');
// 境界を解析して各パートを抽出
$parts = explode($boundary, $data);
// 各パートを処理
foreach ($parts as $part) {
if (empty($part)) {
continue;
}
// ヘッダとデータの分離
$header = substr($part, 0, strpos($part, "\r\n\r\n"));
$body = substr($part, strpos($part, "\r\n\r\n") + 4);
// ヘッダを解析して情報を取得
$headers = explode("\r\n", $header);
$name = preg_match('/name="([^"]+)"/', $headers[0], $matches) ? $matches[1] : '';
$filename = preg_match('/filename="([^"]+)"/', $headers[0], $matches) ? $matches[1] : '';
// パートの処理
if ($name == 'field1') {
// テキストフィールドの処理
echo "Field 1: $body";
} elseif (!empty($filename)) {
// ファイルアップロードの処理
$target_file = 'uploads/' . $filename;
file_put_contents($target_file, $body);
echo "File uploaded: $target_file";
}
}
Node.js
const formidable = require('formidable');
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (err) {
return res.status(500).send( err);
}
// fieldsにはテキストフィールドの値が、filesにはファイル情報が保存されます
console.log(fields);
console.log(files);
// ファイルをアップロードする処理
// ...
});
});
コード例(クライアント側)
HTML
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="text" name="field1">
<input type="file" name="file">
<input type="submit" value="Submit">
</form>
--boundary
Content-Disposition: form-data; name="field1"
value1
--boundary
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
<binary data of the image>
--boundary--
代替方法
URLエンコード
- 例
http://example.com/form?field1=value1&field2=value2
- 方法
各フィールドの値をURLエンコードし、?
で区切ってURLに追加します。 - 用途
複数のテキストフィールドの値を同時に送信する場合。
JSON
- 例
- 方法
データをJSONオブジェクトとしてエンコードし、HTTPリクエストのボディにJSON形式で送信します。 - 用途
構造化されたデータを送信する場合。
{
"field1": "value1",
"field2": "value2"
}
XML
- 方法
データをXML形式でエンコードし、HTTPリクエストのボディにXML形式で送信します。
<data>
<field1>value1</field1>
<field2>value2</field2>
</data>
Base64エンコード
- 方法
バイナリデータをBase64エンコードし、HTTPリクエストのボディに送信します。 - 用途
バイナリデータをテキスト形式に変換して送信する場合。
<binary data>
選択の基準
- エンコード方法
URLエンコードはシンプルなテキストデータの送信に適しています。Base64エンコードはバイナリデータをテキスト形式に変換する場合に使用されます。 - 構造
JSONやXMLは構造化されたデータを送信する場合に適しています。 - データ型
multipart/form-dataは複数のデータ型を同時に送信できるため、ファイルアップロードや複数の異なるデータ型が必要な場合に適しています。
html http forms