如何阻止PHP POST方法提交表单后触发页面重定向
核心原因
原生HTML表单的提交默认是同步跳转模式:点击type="submit"的按钮后,浏览器会直接跳转到action属性指定的地址执行后端代码,这是浏览器内置的默认行为,你现在只在按钮上绑了onclick="change()",没有拦截这个默认事件,自然会触发跳转。另外你贴的PHP代码还有语法错误,就算提交成功也会运行失败。
解决步骤
1. 先修正PHP代码的错误
你现有PHP有两个必触发的问题:
- 超全局变量名写错,是
$_POST不是$POST,漏了前缀下划线 $email_body定义的末尾多了字符串连接符.,会直接报语法解析错误
修正后的send-email.php代码:
<?php // 修正超全局变量写法 $name = $_POST['name']; $visitor_email = $_POST['email']; $message = $_POST['message']; $email_from = '你的发件邮箱地址'; $email_subject = "***Email from Personal Website"; // 删掉行尾多余的连接符 $email_body = "You have received a new message from $name.\n". "Here is the message:\n $message \n"; $to = "你的收件邮箱地址"; $headers = "From: $email_from \r\n"; $headers .= "Reply-To: $visitor_email \r\n"; // 处理完请求返回JSON状态,不要输出多余内容 if(mail($to,$email_subject,$email_body,$headers)){ echo json_encode(['code'=>200, 'msg'=>'发送成功']); }else{ echo json_encode(['code'=>500, 'msg'=>'发送失败,请稍后重试']); } exit; ?>
2. 修改前端代码,拦截默认跳转+异步提交
不要依赖原生表单的同步提交逻辑,直接给表单绑定submit事件,先拦截默认跳转行为,再用AJAX异步发送请求,全程页面不会刷新跳转。
修正后的HTML+JS代码:
<form method="post" name="myemailform" id="myemailform" action="send-email.php"> <input type="text" required placeholder="Name" size="19" name="name" style="width: 15vw"><br><br> <input type="email" required placeholder="Email" name="email" style="width: 15vw"><br><br> <!-- textarea不需要加type属性,删掉冗余的type="text" --> <textarea required placeholder="Message" name="message" style="width: 25vw; height: 15vh; resize: none"></textarea> <br><br> <button type="submit" value="Submit" id="send_button">SEND</button> </form> <script> const form = document.getElementById('myemailform'); const sendBtn = document.getElementById('send_button'); // 绑定表单提交事件,比绑按钮click事件更稳妥,回车提交也能拦截 form.addEventListener('submit', async function(e){ // 核心:阻止浏览器默认的表单跳转行为 e.preventDefault(); // 加防重复提交逻辑 sendBtn.disabled = true; sendBtn.innerText = '发送中...'; try { // 自动收集表单数据 const formData = new FormData(form); // 异步发送POST请求 const res = await fetch(form.action, { method: 'POST', body: formData }); const result = await res.json(); if(result.code === 200){ alert('邮件发送成功!'); form.reset(); }else{ alert(result.msg); } } catch (err) { alert('网络异常,请稍后重试'); } finally { sendBtn.disabled = false; sendBtn.innerText = 'SEND'; } }) // 如果你原来的change()函数有其他交互逻辑,直接把对应代码放到上面的事件回调里即可 </script>
注意事项
- 本地开发环境默认没有配置邮件服务,
mail()函数大概率返回发送失败,需要放到配置好SMTP/发信服务的服务器环境测试 - 不要只在按钮的click事件里写拦截逻辑,用户按回车键也能触发表单提交,直接监听表单的submit事件覆盖所有提交场景
- 上面代码加了发送中禁用按钮的逻辑,避免用户重复点击触发多次发信请求
内容的提问来源于stack exchange,提问作者Matthew Kaplan
相关产品推荐
相关产品推荐

