TLDR: JSON以外はContent-Type不要。
以前作業したコードで、呼び出されたらAjaxを用いて通信し、レスポンスに対応した適当な処理を挟んでから呼び出し元にデータを渡す、いわゆるラッパクラスのようなものが存在する。
今まで、これらの処理はjQuery.ajax()を利用してきたが、今時jQueryというのもよくないのでFetchAPIへ移行する運びとなった。
新しいコードへの移行はかなり簡単に終了することができたが、FetchAPIのContent-Type指定で多少つまずきがあったのでメモ。
FetchAPIでは、POSTを行う際、body
に指定されたデータの型が主要なものであればContent-Typeもそれに合わせて自動的に指定される。例えばString
であればtext/plain;charset=UTF-8
, URLSearchParams
であればapplication/x-www-form-urlencoded;charset=UTF-8
といった具合である。これは仕様に記載されている動作である。
Fetch Standard – https://fetch.spec.whatwg.org/#body-mixin
また、Content-Typeを手動で指定した場合、そちらが優先される。例えばJSON.Stringify()
の返り値はString
であるが、Content-Typeを指定すれば勝手にtext/plain
にされることはなくなる。
この仕様のため、JSONを除けば大概の送信手段はContent-Typeを指定する必要がない。指定してしまうと、データの型と相違があった場合にサーバがリクエストボディをうまく解釈できない場合がある。
特にFormDataの場合、手動でヘッダを指定するとboundary
を無視することになる。そのためデータがサーバに届いたとしても、それを解釈することができない。これのため一時間ほどハマった。
余談として、当時どうしてもうまく送信できなかったのでFetchのPolyfill実装を読んでみたが、Blob
やSearchParams
に関する記述はあるのにFormData
に関する記述が無く困った。XHRでFormDataを判別してContent-Typeに指定しているのか?そのうち調べてみたい。
fetch/fetch.js at master · github/fetch – https://github.com/github/fetch/blob/master/fetch.js#L233
以上です。
コメントを残す