【HTTP】multipart/form-data の boundary って何ぞや？

API の公式ドキュメントには Sample Request がありますよね。

よく使っている [LINEWORKS API](https://developers.worksmobile.com/jp/document/13?lang=ja) でも Sample Request を用意してくれているのですが、記述形式が HTTP Request なのです。

私は Javascript をメインにしているので、Javascript で書かれている Sample なら大助かりなのですが、たいていは違うので Javascript のサンプルコードがないか Qiita や WEB 上を探しています。

んで、そのときによく見かけるのが、タイトルに書いた `Content-Type: multipart/form-data; boundary` ちゃん。
この子のこと、実は私よくわかってないんですけど、検証ツールの [Postman](https://www.postman.com/
) さんのおかげで理解できずとも API は利用できております。

でも、なんかこう、いつまでもよく理解できないままって言うのも悔しいので、ちょっと勉強してみました！(｀・ω・´)
理解した内容をつれづれなるままに記録していきたいと思います。

# まずは HTTP の基本！

API は Application Programming Interface の略です。
最近ようやく空で書けるようになってきました！(*‘∀‘)

公開されている API に提供されている機能を使うには、API の URL に必要事項を添えて
 HTTP Request します。
HTTP Request なので、もちろん HTTP Protocol に沿って書きます。
今までふわっとした知識だったので、今回は MDN のページをよく読んでみました！
[MDN Web Docs HTTP の概要](https://developer.mozilla.org/ja/docs/Web/HTTP/Overview)

・・・さすがに量が多いですね。

取り敢えず今回は API に関することですから、HTTP Request メッセージの部分ですね。

##  HTTP Request メッセージの構造

HTTP Request は以下の要素で構成されてます。

1. HTTP Method（GET、POST など）
2. リソースの URL（API の URL）
3. HTTP プロトコルのバージョン（1.1 か 2）
4. Header 情報（API を利用するときの必要事項とかはココに）
5. Body 情報（POST だと必要だったりなかったり）

## Header 情報内の Content-Type

ようやくタイトルに近づいてきました。
Header 情報に値を設定することで、API サーバーに追加情報を渡すことができます。

その中の一つに `Content-Type` があります。
`Content-Type` は API サーバーにどのような種類のデータを送ったのか教えています。

よく使うのは `text/html` とか `application/json` でしょうか。

## Content-Type: multipart/form-data

ついに今回の本題！`Content-Type: multipart/form-data` です(*'▽')

`multipart/form-data` さんが誰かと言うと、POST による HTTP Request でフォームデータを送信するときに設定します。
特に、ファイルをアップロードする場合に使いますね。

それではアップロードするファイルを指定するにはどうするかと言うと・・・
満を持して `boundary` さんが登場するわけです！

## boundary ～ Content-Type のディレクティブ～

シェフの気まぐれ風～夏の日差しに抱かれて～

MDN Web Docs には、要約するとこう書いてあります。
「`boundary` は Content-Type のディレクティブの一つです」

・・・いや、そもそもディレクティブって何やねん！( ﾟДﾟ)ノ

ググってみたところ、こんな説明が。

```
ディレクティブと言うのは難しい言い方ですが、和訳すると「指示文」となります。
```

難しい言い方なら、わからなくても仕方ないよねー。
関数で言う引数みたいなものですかね。まぁ、そこはざらっと流してしまいましょう。

`boundary` は直訳すると `境界` という意味です。
HTTP Request Header とアップロードするファイルの記述の境界を表しています。

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

と書いてあったら、`----WebKitFormBoundaryxxxxyz` で区切られたら別のファイル情報だよ、という意味になります。つまり、

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

----WebKitFormBoundaryxxxxyz
Content-Disposition: form-data; name="Filedata"; filename="/C:/Users/xxxxx/Desktop/sample.png"
Content-Type: image/png

(data)
----WebKitFormBoundaryxxxxyz
```

上記の場合 `----WebKitFormBoundaryxxxxyz` で囲まれている内容がアップロードしようとしているファイルデータになります。

## つまり、boundary って

自分で好きな値を指定するんですよ！いちおう、お決まりはあるみたいですが。

```
メールゲートウェイを通過しても大丈夫だと知られている文字の中から1～70文字で構成
```

アルファベットと数字の組み合わせが無難ということですね！( ﾟДﾟ)

### どんな文字が使えるかちゃんと調べました【追記】

どうやら、ASCII 英数字といくつかの特殊記号が使えるようです。
`'` `(` `)` `+` `_` `,` `-` `.` `/` `:` `=` `?` `U+0020（空白）`

こちらのサイトにまとまっていました。
[suikawiki multipart/form-data境界文字列](https://wiki.suikawiki.org/n/multipart%2Fform-data%E5%A2%83%E7%95%8C%E6%96%87%E5%AD%97%E5%88%97)

#おわりに
ここまでお付き合いいただきありがとうございました。

いやー、まだまだ知らないことだらけですね。
でも、勉強して理解を深められるのは嬉しいことです(^^)

Qiita の記事投稿も良い復習になります。
インプットしたものをアウトプットして、知識を定着させる。
とても大事。
API の正式名称も空で書けるようになったしね( ﾟДﾟ)ｗ

次は何を書こうかな～。
ではまた！(^^)/

#参考にさせていただきましたm(_ _)m

[MDN Web Docs HTTP の概要](https://developer.mozilla.org/ja/docs/Web/HTTP/Overview)
[MDN Web Docs HTTP ヘッダー Content-Type](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Type)
[ウィキペディア（Wikipedia）- メディアタイプ](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E3%82%BF%E3%82%A4%E3%83%97)
[ディレクティブとは](https://qiita.com/kurodai0715/items/48f7a832312e36417619)
[suikawiki multipart/form-data境界文字列](https://wiki.suikawiki.org/n/multipart%2Fform-data%E5%A2%83%E7%95%8C%E6%96%87%E5%AD%97%E5%88%97)

[LINEWORKS API](https://developers.worksmobile.com/jp/document/13?lang=ja)
[Postman](https://www.postman.com/
)