Nuxt2表单提交重定向、toast提示及人机验证问题求解
Nuxt2联系表单提交+跳转+toast实现方案
问题根因
之前的代码存在几个核心逻辑错误,导致功能冲突:
- 早期使用
mailto:作为表单action无效:该协议只能唤起用户本地邮件客户端,无法自动发送邮件,多数未配置本地邮件客户端的用户根本无法提交表单 - 提交按钮误用
<a>标签:a标签不具备表单提交能力,点击无法触发默认提交逻辑 - 跳转逻辑绑定在form的
@click事件上:用户点击表单任意位置都会直接跳走,无法正常填写内容 - 直接用
@submit.prevent拦截提交后立刻执行路由跳转:相当于完全阻断了表单默认提交行为,数据根本没有发送到formsubmit.co服务端,自然无法触发reCAPTCHA人机验证,也无法正常发信
可行实现方案
方案1:异步提交(推荐,逻辑连贯)
不需要依赖第三方跳转,自主控制提交全流程,不影响reCAPTCHA触发:
- 先修正表单结构,替换a标签为正规submit按钮,给表单加ref方便获取实例:
<template> <form ref="contactForm" action="https://formsubmit.co/你的接收邮箱" method="POST" @submit="handleSubmit" > <div> <div> <input type="text" name="name" id="name" autocomplete="name" placeholder="Name" required> </div> <div class="col-span-6 sm:col-span-3"> <input type="email" name="email" id="email" autocomplete="email" placeholder="Email" required> </div> <div> <textarea name="message" id="message" autocomplete="message" placeholder="Your Message" required></textarea> </div> <!-- 开启formsubmit自带reCAPTCHA验证 --> <input type="hidden" name="_captcha" value="true"> <div class="xl:w-1/3 md:w-1/2 px-4"> <button class="btn black-btn mt-2" type="submit">Send Message</button> </div> </div> </form> </template>
- 编写提交方法,手动发送表单数据,等服务端返回成功后再执行toast和跳转:
export default { methods: { async handleSubmit(e) { e.preventDefault() const form = this.$refs.contactForm const formData = new FormData(form) try { const res = await fetch(form.action, { method: 'POST', body: formData, headers: { 'Accept': 'application/json' } }) if (res.ok) { this.$toast.show('Message sent') form.reset() this.$router.push('/') } else { this.$toast.show('Submission failed, please try again later') } } catch (err) { this.$toast.show('Network error, please check your connection and retry') } } } }
方案2:利用formsubmit自带跳转(无额外异步代码)
如果不想手写异步请求,可以用formsubmit自带的跳转配置,流程更简单:
- 表单内加隐藏的
_next配置项,指定验证通过后的跳转地址,不需要绑定任何submit拦截事件:
<form action="https://formsubmit.co/你的接收邮箱" method="POST"> <!-- 原有表单项保持不变 --> <input type="hidden" name="_next" value="https://你的站点域名/?submit_success=1"> <div class="xl:w-1/3 md:w-1/2 px-4"> <button class="btn black-btn mt-2" type="submit">Send Message</button> </div> </form>
- 在首页的生命周期钩子中判断路由参数,触发toast:
// 首页代码 export default { mounted() { if (this.$route.query.submit_success) { this.$toast.show('Message sent') // 清除url上的参数,避免刷新重复弹toast this.$router.replace({ path: '/', query: {} }) } } }
该方案完全走formsubmit默认提交流程,不会阻断reCAPTCHA验证,不需要写额外的请求逻辑。
内容的提问来源于stack exchange,提问作者EsinYil
相关产品推荐
相关产品推荐

