search
LoginSignup
39
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

curl の POST オプション -d と -F の違いから、改めて MIME type を学ぶ

-d (--data) と -F (--Form)

curl -X POST -d

curl の POST オプションを -d (--data) とした場合、MIME type は application/x-www-form-urlencoded になります。

curl -X POST -d ‘name=taro’

curl -X POST -F

続いて -F (--Form) オプションを使う場合、MIME type は multipart/form-data になります。

curl -X POST -F ‘name=taro’

これら2つの MIME type が使われるシーンは主に HTML フォーム <form> を使う時です。

<form enctype="application/x-www-form-urlencoded"/>
<form enctype="multipart/form-data"/>

では、違いは何でしょうか?

MIME

MIME とは Multipurpose Internet Mail Extension の略です。
Mail Extension は Mail に当初、唯一記載することができた ASCII 英数字以外のデータ (各国語、添付ファイルとか) を取り扱うことができる拡張仕様だったというところから来ているようです。

MIME type

送信先に伝える送信データの種類です。
MIME type の型はこのようになっています。

type/subtype; parameter (ex. text/plain; charset=UTF-8 [デフォルトでは ASCII (US-ASCII) になってます。] )

代表的な MIME type はこのあたりです。

- text/plain(プレーンテキスト)
- text/html(HTML)
- application/xhtml+xml(XHTML)
- image/gif(GIF)
- image/png(PNG)
- video/mpeg(MPEG)
- application/octet-stream(任意のバイナリデータ)
- message/rfc822(RFC 822形式)

個別型 (discrete) とマルチパート型 (multipart)

個別型 (discrete)

実は、上に書いた代表的な MIME type は全て個別型と言われる type です。
個別型は単一の種類の ファイル、メディアを表す type です。

上にも書きましたが代表的な個別型の type は以下です。

  • application: type が明確ではない、あらゆる種類の binary data 。
    application/octet-stream (汎用的な binary data), application/pdf, application/pkcs8, application/zip など。

  • text: テキストのみのデータ。人間が読める。

  • audio: 音声データ。

  • image: 画像データ。

  • video: 動画データ。

  • model: 三次元オブジェクトデータ。

マルチパート型 (multipart)

マルチパート型とは、複数の種類のデータを含む type です。
典型的なところだと、multipart/alternative で、HTMLメールで HTML とプレーンテキストという異なる種類のデータを送る時に使います。

curl の POST オプション -d と -F の違い

知識が揃ったのでタイトルに戻ります。

curl -X POST -d を使った時、MIME type は application/x-www-form-urlencoded になります。
application個別型 の type ですので、単一のデータを送りたい時に使います。
送信されるデータは key1=value2&key2=value2 という形式で、渡す value は URL encoding (percent-encoding) されていることが期待されます。
送信データが name=taro%25&age=10 だとすると、受け取るデータは name: taro!, age: 10 のような感じです。

curl -X POST -F を使った時、MIME type は multipart/form-data になります。
multipartマルチパート型 の type ですので、複数種類のデータを送りたい時に使います。
具体的に言うと、ファイルなどの binary data とテキストを同時に送る時などです。
ドキュメント形式は複数の部分から成り、boundary と呼ばれる -- で始まる文字列によって区切られます。それぞれの部分は固有になっていて、固有の HTTP ヘッダーとして Content-Disposition やファイルアップロードのフィールドには Content-Type を持ちます。
送信データは以下のようなイメージです。

Content-Type: multipart/form-data; boundary=-----boundary

-----boundary
Content-Disposition: form-data; name="TestTextField"

Test
-----boundary
Content-Disposition: form-data; name="sampleFile"; filename="sample.txt"
Content-Type: text/plain

Sample file.
-----boundary

まとめ

  • curl -X POST -d の MIME type は application/x-www-form-urlencoded
  • application/x-www-form-urlencoded個別型 の MIME type で、短い文字列などの単一の種類のデータを POST したい時はこちらを使った方がいい。
  • curl -X POST -F の MIME type は multipart/form-data
  • multipart/form-dataマルチパート型 の MIME type で、文字列とファイルなどの複数種類のデータを同時に POST したい時はこちらを使った方がいい。

おまけ①

書いていて Content-typeMIME type の違いって何だっけ...? となったのですが、

  • MIME type:データの種類
  • Content-Type:データの種類を指定するヘッダーの項目

Content-Type は、あくまでヘッダー項目名で、中に書くのが MIME type と考えれば良さそうでした。

Content-Type: text/plain;

おまけ②

個別型の discrete って記憶に定着しにくそうだなあ...と思っていたら、離散の という意味も含んでいました。
「アナログは連続的、デジタルは離散的。(Analog is continuous, Digital is discrete.)」というので覚えやすくなったはず。

おまけ③

curl -X POST -F (--Form)@ から始まる文字列をファイルとして認識するのやめてくれ〜と困っている方はこんな記事を書いてみたのでチェックしてみて下さい。
https://qiita.com/att55/items/d216458524ab9a1839d2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
39
Help us understand the problem. What are the problem?