axios で express のAPI にリクエストを投げていて何故かうまく値が取れなくてハマってしまったのでメモ。
Express のAPI
const express = require('express'); const app = express(); const Joi = require('@hapi/joi'); const validation = (data) => { const schema = Joi.object({ email: Joi.string().required().email(), password: Joi.string().min(6).required(), }); return schema.validate(data, { abortEarly: false }); }; app.post('/api/login', (req, res) => { const { error } = validation(data); if( error ) { res.json({ message: 'welcome to the API' }); } else { const errorMessages = error.details.map((data) => data.message); res.status(400).send(errorMessages.join("\n")); } }); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.listen(3000, () => console.log('Server started !'));
問題のあったコード
import axios from 'axios'; axios.defaults.headers.common['content-type'] = 'application/json'; const getPosts = await (data) => { try { const res = await axios.post(API_SIGNUP, data); return res; } catch (err) { throw err; } };
API を叩くので常に content-type: application/json
にしたかったので default.headers
で設定したのですが email is required, password is required
とPOSTしているはずのデータがバリエーションで弾かれるエラーになって返ってくるばかりでした。
POST したデータは Express では req.body
に入ってくるので、これを console.log してみたところ空オブジェクト{}
になっていました。(POST した筈のデータがが消えている… なーぜー?)
GET / POST メソッドの headers
オプションで content-type
を設定すると res.body
でデータが取れ問題なく動作する
import axios from 'axios'; const getPosts = await (data) => { try { const res = await axios.post(API_SIGNUP, data, { headers: { content-type: 'application/json', } }); return res; } catch (err) { throw err; } };
Request Header に違いがあった
GET / POST の headers
オプションで content-type
を指定すれば問題なく動作していたことから、 API 側ではなくフロントの送り方に問題があるのではと推察しました。
送信されるリクエストを見比べていたところ Request Headersの content type に違いが出ていました。
axios.defaults.headers.common['content-type'] = 'application/json';
で送信したリクエスト
[content-type]: application/json, application/json;charset=utf-8
axios.post(url, data, { headers: { 'content-type': 'application/json' } })
で送信したリクエスト
[content-type]: application/json
defaults.headers
オプションで送信した Request Header の Content-Type は axios が自動的に application/json;charset=utf-8
を付けているようで application/json
が二重になっています。🤔 🤔 🤔
Defaults.headers で Content-Type を設定する時は Content-Type
でなければならない
defaults.headers
で設定していた Content-Type のキーが content-type
と小文字になっていたことが問題でした。
🙅
axios.defaults.headers.common['content-type'] = 'application/json';
- [Request Header]:
application/json, application/json;charset=utf-8
req.body => {}
🙆
axios.defaults.headers.common['Content-Type'] = 'application/json';
- [Request Header]:
application/json
req.body => { foo: bar, … }
🙅
axios.defaults.headers.common['Content-type'] = 'application/json';
- [Request Header]:
application/json, application/json;charset=utf-8
req.body => {}
🙅
axios.defaults.headers.common['content-Type'] = 'application/json';
- [Request Header]:
application/json, application/json;charset=utf-8
req.body => {}
default.headers
オプションで Content-Type を設定する時は C と T が大文字の Content-Type
でなければ application/json;charset=utf-8
が追加で付けられてしまうようです。
GET / POST のオプションの方は大文字小文字の区別なく受け入れられる
🙆
axios.post(url, data, {headers: {'content-type': 'application/json'}});
- [Request Header]:
application/json;char
req.body => { foo: bar, … }
🙆
axios.post(url, data, {headers: {'Content-Type': 'application/json'}});
- [Request Header]:
application/json;char
req.body => { foo: bar, … }
🙆
axios.post(url, data, {headers: {'Content-type': 'application/json'}});
- [Request Header]:
application/json;char
req.body => { foo: bar, … }
🙆
axios.post(url, data, {headers: {'content-Type': 'application/json'}});
- [Request Header]:
application/json;char
req.body => { foo: bar, … }
恐らく toLowerCase()
されているのだと思います。 headers: { 'cOntEnt-type': 'application/json' }
みたいな設定にしても問題ありませんでした。
もしかしたら Express の express.json()
の type
オプションを上手く変えれば問題なかったのかもしれませんが、axios の default.header オプションでの Content-Type の設定は "Content-Type"
という固定の文字列でしか設定できない仕様になっているのが原因だったようです。
あーハマった!
- GitHub - axios/axios: Promise based HTTP client for the browser and node.js
- Express 4.x - API リファレンス

- 作者:mio
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)

Axios: Celebrating the Hymns of Greek Orthodox America
- 発売日: 2011/12/22
- メディア: MP3 ダウンロード