表单提交后阻止页面刷新失效:e.preventDefault()无法生效的问题排查与解决
解决表单提交后页面自动刷新的问题
我看了你的代码,问题主要出在事件绑定错误,以及没有用异步方式处理表单提交这两个地方,咱们一步步来解决:
为什么e.preventDefault()没生效?
你写的JS代码是给按钮#add绑定submit事件,但按钮本身并没有submit事件——submit事件是属于<form>元素的。当你点击提交按钮时,触发的是表单的默认提交行为,而你的监听代码根本没被触发,所以阻止默认刷新的逻辑完全没起作用。
完整解决方案
1. 修正事件绑定,改用AJAX异步提交表单
首先把JS代码改成监听表单的submit事件,同时用FormData处理文件上传(因为你的表单包含文件,普通AJAX提交没法处理文件):
// 确保先引入jQuery,比如在页面底部添加:<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> $("#form").submit(function(e) { e.preventDefault(); // 彻底阻止表单默认提交刷新行为 // 创建FormData对象,自动收集表单所有数据(包括文件) const formData = new FormData(this); // 发送AJAX请求到当前页面的PHP处理逻辑 $.ajax({ url: window.location.href, type: 'POST', data: formData, contentType: false, // 必须设为false,让浏览器自动处理文件上传的边界 processData: false, // 必须设为false,避免jQuery把FormData转成字符串 success: function(response) { // 根据PHP返回的结果做对应处理 switch(response) { case "success": alert("食谱添加成功!"); // 刷新图片列表(后面会调整HTML结构方便更新) $.get(window.location.href, data => { $('#image-container').html($(data).find('#image-container').html()); // 重置表单 $('#form')[0].reset(); }); break; case "upload_failed": alert("图片上传失败,请重试!"); break; case "db_failed": alert("数据库保存失败,请检查SQL语句!"); break; case "fill_form": alert("请填写完整的表单内容!"); break; default: alert("提交出错,请稍后再试!"); } }, error: () => alert("请求发送失败,请检查网络!") }); });
2. 调整PHP代码,适配AJAX请求
原来的PHP代码在页面加载时就会执行addrecipe(),而且直接输出HTML内容,这会干扰AJAX的响应。我们需要修改PHP,让它只在AJAX提交时处理表单,并且只返回状态结果:
<?php function displayimage() { $con = mysqli_connect("localhost", "root", "", "cookbook"); $result = mysqli_query($con, "SELECT * FROM product"); while ($row = mysqli_fetch_array($result)) { // 修正原代码的语法错误:多了一个多余的点 echo "<img src='uploads/".$row['image']."' class='imageaaa'>"; } mysqli_close($con); } function addrecipe() { if (isset($_POST["Add"])) { $con = mysqli_connect("localhost", "root", "", "cookbook"); if (!empty($_POST["Name"])){ $name = $_POST["Name"]; $type = $_POST["Type"]; $image = $_FILES['Image']['name']; $date = date("d.m.Y, G:i"); // 重点:用预处理语句防止SQL注入,绝对不能直接拼接用户输入到SQL里! $sql = "INSERT INTO product(`name`, `type`, `image`, `date`) VALUES(?, ?, ?, ?)"; $stmt = mysqli_prepare($con, $sql); mysqli_stmt_bind_param($stmt, "ssss", $name, $type, $image, $date); $dbSuccess = mysqli_stmt_execute($stmt); if($dbSuccess){ $target = "uploads/".basename($image); if (move_uploaded_file($_FILES['Image']['tmp_name'], $target)) { echo "success"; // 返回成功状态 } else { echo "upload_failed"; } } else { echo "db_failed"; } mysqli_stmt_close($stmt); } else { echo "fill_form"; } mysqli_close($con); exit; // 处理完AJAX请求后立即退出,避免输出页面其他内容 } } // 只有当表单提交时才执行处理逻辑 if(isset($_POST["Add"])){ addrecipe(); } ?>
3. 调整HTML结构,优化交互体验
把图片列表放到单独的容器里,方便AJAX更新;同时修正原代码里的<be>笔误(应该是<br>):
<!-- 用容器包裹图片列表,方便后续AJAX更新 --> <div id="image-container"> <?php displayimage(); ?> </div> <form method="POST" id="form" enctype='multipart/form-data'> Name: <input type="text" name="Name" value="<?php echo isset($_POST['Name'])?htmlspecialchars($_POST['Name'], ENT_QUOTES):'';?>"><br> Type: <select name="Type" required> <option value="dishes" disabled selected hidden>Wybierz typ</option> <option value="dishes">Dania</option> <option value="desserts">Desery</option> <option value="snacks">Przekąski</option> </select><br> Image (jpg, png): <input type="button" id="loadFileXml" value="loadXml" onclick="document.getElementById('upload_image').click();" /> <input type="file" style="display:none;" id="upload_image" name="Image"> <br><br> <!-- 其他表单元素 --> <button name="Add" id="add">提交食谱</button> </form> <!-- 引入jQuery,放在页面底部 --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- 上面的AJAX代码放在这里 --> <script> // 这里写之前的AJAX代码 </script>
额外注意事项
- 确保你的
uploads文件夹存在且有写入权限,否则图片上传会失败。 - 原代码里的防重复提交JS(
window.history.replaceState)可以删掉了,因为AJAX提交不会触发页面刷新,也就不会出现重复提交的弹窗。 - 一定要保持预处理语句的使用,避免SQL注入漏洞,这是Web开发的基本安全要求。
内容的提问来源于stack exchange,提问作者Astw41
相关产品推荐
相关产品推荐

