$_POST
や filter_input
でデータを取得しているようなPHPのバックエンドにフォームデータを axios で送信する時 Content-Type を application/x-www-form-urlencoded
にするだけでは上手くいきません。
🙅♀️ Content-Type: application/x-www-form-urlencoded でも上手く行かない例
バックエンド (PHP)
<?php addRoute('POST', '/login', login); function login() { $email = filter_input(INPUT_POST, 'email'); $password = filter_input(INPUT_POST, 'password'); // ログイン処理 }
フロントのフォーム送信部分
const data = { email: 'example@example.com', password: 'password', }; await axiso.post('/login', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, });
バックエンドで $email
, $password
が空文字列になるので上手く行かない。
この送り方だと $POST
が次のような形になっている
<?php function login() { var_dump($_POST); // => {{"email":"example2@example_com","password":"123456"}: ""} }
🙆♀️ axios で フォームデータを送る時は URLSearchParams を使う
送信するデータを URLSearchParams
の形式にする必要がある
const data = { email: 'example@example.com', password: 'password', }; const params = new URLSearchParams(); Object.keys(data).forEach(function(key) { params.append(key, this[key]); }, data); await axiso.post('/login', params, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, });
👇
$_POST
が {email: "example2@example.com", password: "123456"}
という形になるので、バックエンドの $_POST
や filter_input
でフロントから送られたデータが正しく取得できるようになりました! ₍ ᐢ. ̫ .ᐢ ₎👌
公式のドキュメントには qs
というパッケージを使う方法も載っていました。
import qs from 'qs'; const data = { 'bar': 123 }; const options = { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, data: qs.stringify(data), url, }; axios(options);cf. GitHub - axios/axios: Promise based HTTP client for the browser and node.js
所感
ちゃんとドキュメント読もうって事でした。
思い出せば、jQuery の ajax
だと Object をそのまま送っても $_POST
で取得できていた記憶があったので、jQuery 君、今までは君がいい感じに変換してくれてたんだね…って思ったのでした。
[参考]
- GitHub - axios/axios: Promise based HTTP client for the browser and node.js
- URLSearchParams - Web API | MDN
- axios で POST する際、Content-type を application/x-www-form-urlencoded にしたい時どうするか - Qiita
- jQueryでAjaxを使ってPost送信をする方法:$.post() | UX MILK