window.location.href在表单提交场景下无法兼顾存库与跳转
问题根因
- 原生submit提交模式下:PHP执行完入库操作后没有配置主动跳转逻辑,页面停留在当前提交页刷新,无法触达结果页
- img元素触发Sort()模式下:整个流程没有触发表单的默认POST提交事件,PHP端收不到$_POST传递的答题数据,自然不会执行入库操作,仅完成了客户端的页面跳转
落地方案
核心调整思路
拆分原有混杂的逻辑:前端仅做答题合法性校验,表单提交、数据入库、结果跳转全部由服务端接管,避免客户端跳转和表单提交的流程冲突。
代码修改步骤
1. 调整前端表单结构
替换原有原生submit按钮,用内置图片提交能力的input替代img元素,保留自定义样式的同时不脱离表单提交流程:
<form id="compassform" name="compass" method="post" onsubmit="return validateAnswer()"> <!-- 原有所有题目的radio输入保持name=q1、name=q2...的结构不变 --> <!-- 用type=image的输入项替代原来的img提交按钮 --> <input type="image" src="../pics/process.png" style="border:none;" alt="提交答题"> </form>
2. 重构前端校验逻辑
将原有Sort()函数里的页面跳转逻辑移除,仅保留答题校验能力,校验通过后放行表单默认提交:
function validateAnswer() { // 原有单选校验逻辑完全保留 if (compass.q1[0].checked == true) { party1 += 1; } else if (compass.q1[1].checked == true) { party2 += 1; } else { alert("Please answer question 1."); return false; // 校验不通过,阻止表单提交 } if (compass.q2[0].checked == true) { party1 += 1; } else if (compass.q2[1].checked == true) { party2 += 1; } else { alert("Please answer question 2."); return false; // 校验不通过,阻止表单提交 } // 校验通过,放行表单提交,不在这里写前端跳转 return true; }
3. 修正PHP入库与跳转逻辑
- 先修复原有SQL语句的bug:原代码中q6字段的取值错误复用了$_POST['q7'],会导致入库数据错误
- 入库操作完成后,直接通过服务端头信息跳转结果页,跳过前端刷新环节
<?php // 仅在收到POST提交请求时执行入库与跳转逻辑 if ($_SERVER['REQUEST_METHOD'] === 'POST') { $link = mysqli_connect("localhost","username","password", "database"); if (mysqli_connect_error()) { die ("There was an error connecting to the database"); } // 修正字段取值错误的问题 $query = "INSERT INTO `users` (`q1`, `q2`, `q3`, `q4`, `q5`, `q6`, `q7`, `q8`) VALUES ( '".mysqli_real_escape_string($link, $_POST['q1'])."', '".mysqli_real_escape_string($link, $_POST['q2'])."', '".mysqli_real_escape_string($link, $_POST['q3'])."', '".mysqli_real_escape_string($link, $_POST['q4'])."', '".mysqli_real_escape_string($link, $_POST['q5'])."', '".mysqli_real_escape_string($link, $_POST['q6'])."', '".mysqli_real_escape_string($link, $_POST['q7'])."', '".mysqli_real_escape_string($link, $_POST['q8'])."' )"; if (mysqli_query($link, $query)) { // 服务端计算党派匹配得分 $party1 = 0; $party2 = 0; if ($_POST['q1'] == '对应第一党选项值') $party1 +=1; if ($_POST['q1'] == '对应第二党选项值') $party2 +=1; if ($_POST['q2'] == '对应第一党选项值') $party1 +=1; if ($_POST['q2'] == '对应第二党选项值') $party2 +=1; // 入库成功后直接跳转结果页,必须加exit终止后续代码执行 header("Location: ./australiacompassresult.php?p1=".$party1."&p2=".$party2); exit; } } ?>
注意事项
- 不要在前端完成页面跳转后再发起POST请求,跨页面传递POST数据会失效,PHP端永远收不到答题数据
- PHP中使用header跳转时,必须确保页面没有任何提前输出的内容,否则会触发header报错导致跳转失败
- 原有img元素如果一定要保留使用,需要将onclick的逻辑修改为:先运行校验函数,校验通过后手动调用
document.forms['compass'].submit()触发表单提交,不要直接在onclick里写跳转逻辑
内容的提问来源于stack exchange,提问作者Goran Mitrovski
相关产品推荐
相关产品推荐

