起こっている問題
SpringBoot + Vue3.jsでWebアプリを開発していたときに、axiosでフォームのデータをPOSTしようとするとなぜかGET通信になりました。
コード例
AuthFormComponent.vue
<template>
<form>
<div>
<label for="email">メールアドレス</label>
<input
v-model="email"
type="email"
name="email"
id="email"
/>
</div>
<div>
<label for="password">パスワード</label>
<input
v-model="password"
type="password"
name="password"
id="password"
/>
</div>
<div>
<button @click="submit">送信</button>
</div>
</form>
</template>
<script>
import { defineComponent } from '@vue/composition-api';
import axios from 'axios';
import { ref } from 'vue';
export default defineComponent({
setup() {
const email = ref('');
const password = ref('');
const submit = () => {
axios
.post('/login', {
email: email.value,
password: password.value,
})
.then(() => {
console.log('post通信に成功しました');
});
};
return {
email,
password,
submit,
};
},
});
</script>
結果

このように、なぜかGET通信になってしまいました…。
試したこと
URLSearchParams
を使ってみる
この記事を参考にして、URLSearchParams
で書いてみました。
AuthFormComponent.vue
<script>
import { defineComponent } from '@vue/composition-api';
import axios from 'axios';
import { ref } from 'vue';
export default defineComponent({
setup() {
const email = ref('');
const password = ref('');
const submit = () => {
// この部分を修正
let params = new URLSearchParams();
params.append('email', email.value);
params.append('password', password.value);
axios.post('/login', params).then(() => {
console.log('post通信に成功しました');
});
};
return {
email,
password,
submit,
};
},
});
</script>

相変わらずGET通信です…。
そもそも今回はSpringBootのRestController
でJSONを受け取れるので、URLSearchParams
でクエリパラメータを操作する必要がありません。
結論
原因
form
タグの中にbutton
タグがあると、クリック時に通常のフォームの処理が行われます。このコードだとform
タグのmethod
属性が指定されていないので、デフォルトのGET通信が行われることになります。
解決策①
結局axiosで送信するから、form
タグではなくてdiv
タグにする
AuthFormComponent.vue
<template>
<!-- formタグからdivタグに変える -->
<div>
<div>
<label for="email">メールアドレス</label>
<input
v-model="email"
type="email"
name="email"
id="email"
/>
</div>
<div>
<label for="password">パスワード</label>
<input
v-model="password"
type="password"
name="password"
id="password"
/>
</div>
<div>
<button @click="submit">送信</button>
</div>
</div>
</template>
解決策②
button
タグを単なるボタンとして扱うために、type
属性をbutton
にする
AuthFormComponent.vue
<template>
<form>
<div>
<label for="email">メールアドレス</label>
<input
v-model="email"
type="email"
name="email"
id="email"
/>
</div>
<div>
<label for="password">パスワード</label>
<input
v-model="password"
type="password"
name="password"
id="password"
/>
</div>
<div>
<!-- type属性をbuttonにする -->
<button
type="button"
@click="submit"
>
送信
</button>
</div>
</form>
</template>
結果


POST通信に成功しました!!
終わりに
結論だけ見ると、かなり初歩的なところでつまづいていました。ただ、ライブラリやフレームワークを使っていると、こういった予想外のところでつまづくことが結構あります。いい勉強になりました…。