1. ホーム
  2. http

[解決済み] application/x-www-form-urlencoded or multipart/form-data?

2022-03-18 22:40:33

質問

HTTPでは、データをPOSTする方法は2つあります。 application/x-www-form-urlencodedmultipart/form-data . ほとんどのブラウザは、ファイルをアップロードする際に multipart/form-data が使用されています。APIコンテキスト(ブラウザが関与しない)において、エンコードタイプの1つを使用する際の追加ガイダンスはあるのでしょうか?例えば、以下のようなものが考えられます。

  • データサイズ
  • 非ASCII文字の有無
  • エンコードされていない)バイナリデータ上の存在
  • 追加データ(ファイル名など)の転送の必要性

私は基本的に、異なるcontent-typesの使用に関する正式なガイダンスを、これまでのところウェブ上で見つけていません。

どのように解決するのですか?

TL;DR

要約;もしバイナリ(非英数字)データ(またはかなりの大きさのペイロード)を送信する場合は、次のように使用します。 multipart/form-data . それ以外の場合は application/x-www-form-urlencoded .


ご指摘のMIMEタイプは、次の2つです。 Content-Type ヘッダは、ユーザーエージェント (ブラウザ) がサポートしなければならない HTTP POST リクエストのためのものです。 これらのタイプのリクエストの目的は、どちらもサーバーに名前と値のペアのリストを送信することです。 送信されるデータの種類と量に応じて、どちらかの方法がより効率的になります。 その理由を理解するには、それぞれが隠れてやっていることを見る必要があります。

について application/x-www-form-urlencoded の場合、サーバーに送られる HTTP メッセージのボディは基本的に巨大なクエリ文字列です。 & )、名前と値の間は等号で区切られます( = ). その例としては、次のようなものがある。 

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

によると 仕様 :

[予約済みおよび] 英数字以外の文字は、パーセント記号とその文字のASCIIコードを表す2桁の16進数である `%HH' で置き換えられます。

つまり、ある値の中に存在する英数字以外のバイト1つに対して、それを表現するために3バイトが必要になるということです。 大きなバイナリファイルでは、ペイロードを3倍にすることは非常に非効率的です。

そこで multipart/form-data が登場します。 名前と値のペアを送信するこの方法では、各ペアはMIMEメッセージの"part"として表現されます(他の回答で説明したとおりです)。 パートは特定の文字列の境界で区切られます(この境界文字列が"value"のペイロードのどれにも出現しないように特別に選択されます)。 各パートは、次のような独自のMIMEヘッダーのセットを持ちます。 Content-Type であり、特に Content-Disposition それぞれの名前と値のペアの値の部分は、MIMEメッセージのそれぞれの部分のペイロードです。 MIME仕様では、値のペイロードを表現する際に、より多くのオプションを提供しています。帯域幅を節約するために、バイナリデータのより効率的なエンコーディングを選択することができます(たとえば、ベース64やraw binaryなど)。

なぜ multipart/form-data を常に使用するのでしょうか? 短い英数字の値(ほとんどのウェブフォームのような)については、すべてのMIMEヘッダを追加するオーバーヘッドは、より効率的なバイナリエンコーディングによる節約を大幅に上回ると思われます。