enctype='multipart/form-data'ってなんだ?
こんにちは、MUGENUPアルバイトの倉成です。
今回は僕が前々から気になっていた、フォームからファイルを送信するときのおまじないenctype="multipart/form-data"
について調べてみたので、得られた知識をまとめて見ようと思います。
また、マルチパートの情報を検索していると、HTMLのフォームだけではなく、メールのマルチパートの情報に当たることも多くありました。 調べてみると、HTMLの仕様と電子メールの仕様が似ているのは、どうやら歴史的な経緯があるようなので、後半ではインターネット成長の歴史についても少しだけ触れてみようと思います。
multipart/form-data
: ファイルを送るおまじない
それでは、フォームでファイルをアップロードするシチュエーションを考えましょう。
ファイルアップロードをする場合input要素は<input type="file" />
を使い、その親のform
要素には以下のようにenctype="multipart/form-data"
と書く必要があります。
<form action="URI" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> </form>
さて、このおまじないenctype="multipart/form-data"
はなぜ必要なのでしょうか?
Firebugを使ってリクエストを見る
今回はenctype
の有無によりHTTPリクエストのパラメータがどのように変化するかFirefoxのプラグインであるFirebugを使って調べてみようと思います。
なお、今回使用するhtmlのソースコードは
<html> <!-- enctype指定あり --> <form action="http://localhost:4567" method="post" enctype="multipart/form-data"> <input type="file" name="datafile" /> <input type="submit" name="submit_btn" /> </form> <!-- enctype指定なし --> <form action="http://localhost:4567" method="post"> <input type="file" name="datafile" /> <input type="submit" name="submit_btn" /> </form> </html>
で、送信するファイルは
hello world! hogehoge fugafuga
とします(添付ファイル名はsample.txtです)。
さて、それぞれを試したところFirebugは以下の画像のようになりました。
enctype指定あり
enctype指定なし
enctype指定ありでは、Content-Disposition
やContent-Type
など添付ファイルに関する情報とともに、ファイルの本文の情報が存在することが分かります。今回はテキストですが、画像や音声などバイナリの情報でも、同様にここにデータが格納されます。
また、--------
で始まる行があることも特徴的です。
enctype指定なしでは、filedata
にファイル名の情報のみが与えられていて、添付ファイルの情報は見当たりません。
どうも、inputエリアにファイル名のみを指定した
と同様な印象を受けます。
つまり、enctype="multipart/form-data"
を指定しない場合、添付ファイルの情報を送信できていないので、サーバー側では添付ファイルを扱えないという事になりそうです。
なお、-----------------------------146617270317...
のような区切り文字をboundary
と呼び、この区切りを使って複数のパートに分割することからマルチパートと呼ばれているようです。boundary
を使うと入れ子構造も再現できるようです、興味のある方は以下のリンクが詳しくまとまっているので御覧ください。
フォームよるファイルアップロードの仕様 - Jakarta Commons FileUploadの利用手順
メールの場合は
boundary
を使ってファイルの情報を送信するというのがmultipart/form-data
の仕組みでした。
しかし、冒頭で述べたようにメールにも同様のマルチパートという仕組みがあるようです。
では、これまで見てきたフォームのマルチパートはメールのマルチパートとどのような関係があるのでしょうか?
ここでは「Webを支える技術」の引用をさせていただきます。
HTTPの最初のバージョン0.9にはヘッダがありませんでした。HTTPの仕様策定が進められるに従って、HTTPで転送する本文のメタデータを表現するために電子メールのメッセージ仕様(RFC822)のヘッダ形式を借りてくる形で追加されました。
Webを支える技術 P.126
つまり本記事では、formつまりHTTPのマルチパートを先に紹介していたのですが時系列で言うとこれは逆で、HTTPの仕様策定時に電子メールの仕様を参考にしたというのが歴史的な流れのようです。マルチパートに限らず、HTTPの仕様が電子メールの仕様に似ているのはこのような経緯があるためなのですね。
なぜ電子メールの仕様にマルチパートが加わったのか(MIMEが策定されたのか)については
で詳しく解説されています。
ざっくりというとMIME策定前の仕様ではメールのヘッダ・本文がASCII限定で、日本語など非ASCIIの言語が正しく認識できなかったり、添付ファイルがうまく扱えなかったという問題があったようです。
multipart/alternative
:textとhtmlを同時送信
「マルチパート メール」などで検索してヒットする記事にはmultipart/alternative
に関する記事も多いようです。
multipart/alternative
はマルチパートの構造を利用して一つのメールにtext
版とhtml
版の2つの内容を含めて送信し、メーラーの設定次第でtext
かhtml
を選択して表示できるものです。
-----------------------------1948084979928559891542425288 はじめに こんにちはMUGENUPの倉成です。 -----------------------------1948084979928559891542425288 <h1>はじめに</h1> <b>こんにちは</b>MUGENUPの倉成です。 -----------------------------1948084979928559891542425288--
こんなメールを送ると、メーラーの設定次第でプレーンテキストでもリッチテキストでも表示できるようになるわけですね。
さいごに
enctype
を見るたびに「これ、なんだろうなぁー」と思っていたことから始まり、調べて行ったらインターネット成長の歴史的な経緯まで知ることができて、楽しい夏休みの自由研究となりました。
RFCの仕様も機会があればもう少し読んでみようと思います。
HTTPの仕様やRFC策定の歴史については山本陽平さんの「Webを支える技術」を参考にさせていただきました。 URI設計やステータスコード、JSON、HTTPメソッドの使い分けなど基礎的な情報が網羅されているので、特にWebプログラミングが初めてのエンジニアさんにおすすめの一冊です。