HTTPにはデータをPOSTする方法が2つあります。それは application/x-www-form-urlencoded
と multipart/form-data
です。ほとんどのブラウザは、multipart/form-data
を使用した場合にのみ、ファイルをアップロードすることができると理解しています。APIのコンテキスト(ブラウザが関与しない)で、エンコーディングタイプのいずれかを使用する場合の追加ガイダンスはありますか?例えば、以下のようなことが考えられます。
これまでのところ、異なるコンテントタイプの使用に関する正式なガイダンスはウェブ上にありません。
TL;DR。
まとめ; バイナリ(英数字以外)のデータ(またはかなりのサイズのペイロード)を送信する場合は、multipart/form-data
を使用してください。それ以外の場合は、application/x-www-form-urlencoded
を使用してください。
あなたがおっしゃるMIMEタイプとは、ユーザーエージェント(ブラウザ)がサポートしなければならないHTTP POSTリクエストの2つのContent-Type
ヘッダーのことです。 これらのタイプのリクエストの目的は、名前と値のペアのリストをサーバーに送信することです。 送信されるデータの種類と量に応じて、いずれかの方法が他の方法よりも効率的になります。 その理由を理解するには、それぞれが水面下で何をしているかを見る必要があります。
application/x-www-form-urlencodedでは、サーバーに送信されるHTTPメッセージの本文は、基本的に1つの巨大なクエリ文字列です。名前と値のペアはアンパサンド(
&)で区切られ、名前と値はイコールシンボル(
=`)で区切られます。 例えば、次のような例があります:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo`。
仕様書](http://www.w3.org/TR/html401/interact/forms.html)によると、このようになります。
\Reserved and\」の英数字以外の文字は、パーセント記号とその文字のASCIIコードを表す2桁の16進数である「%HH」に置き換えられます。
つまり、値の中に存在する英数字以外のバイト1つにつき、それを表現するために3バイトが必要になるということです。 大きなバイナリファイルの場合、ペイロードを3倍にすることは非常に効率が悪くなります。
そこで、multipart/form-data
の出番です。 名前と値のペアを送信するこの方法では、各ペアはMIMEメッセージの「パート」として表現されます(他の回答で説明されています)。 パートは、特定の文字列の境界で区切られています(この境界文字列が「値」のペイロードのどれにも現れないように、特に選択されています)。 各パートは、Content-Type
や、特にContent-Disposition
などの独自のMIMEヘッダのセットを持ち、各パートに "名前 "を与えることができます。 各名前/値のペアの値の部分は、MIMEメッセージの各パートのペイロードです。 MIME仕様では、値のペイロードを表現する際に、より多くのオプションが用意されています。バンド幅を節約するために、より効率的なバイナリデータのエンコーディングを選択することができます(たとえば、ベース64や生のバイナリなど)。
なぜ multipart/form-data
を常に使用しないのですか? ほとんどのウェブフォームのような短い英数字の場合、すべての MIME ヘッダーを追加することによるオーバーヘッドは、より効率的なバイナリエンコーディングによる節約を大幅に上回るでしょう。
HTTPはmultipartやx-ww-form-urlencodedでのPOSTに限らないと思います。Content-Type Header]1は、HTTPのPOSTメソッドとは直交しています(自分に合ったMIMEタイプを記入できます)。これは、典型的なHTML表現ベースのウェブアプリケーションの場合も同様です(例えば、ajaxリクエストのペイロードを送信するためにjsonペイロードが非常に普及しました)。
HTTP上のRestful APIに関して、私が接した最も一般的なコンテンツタイプは、application/xmlとapplication/jsonでした。
バイナリデータを独自のアセット/リソースとして表現することを試みます。呼び出し回数は増えますが、分離がうまくいきます。画像の例です。
POST /images
Content-type: multipart/mixed; boundary="xxxx"
... マルチパートデータ
201 作成
Location: http://imageserver.org/../foo.jpg
それ以降のリソースでは、単純にバイナリリソースをリンクとしてインライン化することができます。
[2]: https://stackoverflow.com/questions/1443158/binary-data-in-json-string-something-better-than-base64
私はManuel氏の発言の多くに同意します。実際、彼のコメントはこのURLを参照しています...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
...以下のように書かれています。
コンテンツタイプ application/x-www-form-urlencoded "というコンテンツタイプは 大量のバイナリデータやテキストを送信するには非効率的です。 大量のバイナリデータや非ASCII文字を含むテキストを 非ASCII文字を含むテキストを大量に送信するには非効率的です。コンテンツタイプが コンテントタイプ「multipart/form-data」は ファイルや非ASCIIデータを含むフォームを送信する際には ファイル、非ASCIIデータ、バイナリデータを含むフォームの送信には およびバイナリデータを含むフォームを送信する際に使用してください。
しかし、私にとっては、ツールやフレームワークのサポートに帰結します。
ユーザーのことを明確に把握し、彼らがどのようにAPIを利用するのかを知ることができれば、それが判断の助けになります。APIユーザーにとってファイルのアップロードが困難であれば、ユーザーは離れていくでしょうし、サポートに多くの時間を費やすことになるでしょう。
そのためには、あなたがAPIを作成する際にどのようなツールをサポートしているか、また、あるアップロード・メカニズムを他のメカニズムに比べてどれだけ簡単に対応できるかが重要になります。