Bootstrap Modal数据展示问题:首次点击搜索页面刷新且弹窗不显示
解决Bootstrap Modal首次点击不展示数据库查询结果的问题
核心问题分析
点击搜索按钮时,表单默认提交会触发页面刷新,导致Modal还没来得及显示就被打断;刷新后页面保留了POST请求的搜索参数,再次点击时Modal能加载到之前查询的结果。要实现首次点击直接展示数据,必须阻止表单默认提交行为,改用AJAX异步获取数据并动态填充Modal。
具体修改方案
- 阻止表单提交默认行为:通过JavaScript监听表单提交事件,调用
preventDefault()避免页面刷新。 - 修复SQL注入风险:使用PDO参数绑定替代直接变量拼接,确保数据库查询安全。
- AJAX异步获取数据:发送搜索请求到后端,接收返回的HTML结果后填充到Modal,再主动打开Modal。
- 分离前后端逻辑:单独处理AJAX请求的数据库查询,避免页面加载时的冗余执行。
修改后的完整代码
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <title>Plot Search</title> </head> <body> <!-- Modal --> <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Search Result</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body" id="modal-body-content"> <!-- 结果将通过AJAX动态填充 --> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> </div> </div> </div> <form id="search-form"> <label>Search Plot Number:</label> <input type="text" name="search" required> <button type="submit" class="btn btn-primary">Search</button> </form> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <script> $(document).ready(function() { $('#search-form').submit(function(e) { // 阻止表单默认提交行为 e.preventDefault(); // 获取搜索关键词 var searchValue = $('input[name="search"]').val(); // AJAX请求获取数据 $.ajax({ url: '', // 当前页面处理AJAX请求 method: 'POST', data: { ajax_search: true, search: searchValue }, success: function(response) { // 将返回的结果填充到Modal body $('#modal-body-content').html(response); // 打开Modal $('#exampleModal').modal('show'); }, error: function() { $('#modal-body-content').html('<p>Error fetching data. Please try again.</p>'); $('#exampleModal').modal('show'); } }); }); }); </script> <?php // 处理AJAX请求 if(isset($_POST['ajax_search'])) { $con = new PDO("mysql:host=localhost;dbname=blog",'root',''); // 使用参数绑定防止SQL注入 $sth = $con->prepare("SELECT * FROM `data` WHERE plotnumber = :plotnum"); $sth->bindParam(':plotnum', $_POST['search']); $sth->setFetchMode(PDO::FETCH_OBJ); $sth->execute(); if($row = $sth->fetch()) { ?> <table class="table table-bordered"> <thead> <tr> <th>Plot Number</th> <th>Plot Detail</th> <th>Verified</th> <th>Size</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td><?php echo $row->plotnumber; ?></td> <td><?php echo $row->plotdetail;?></td> <td><?php echo $row->verified;?></td> <td><?php echo $row->size;?></td> <td><?php echo $row->status;?></td> </tr> </tbody> </table> <?php } else { echo "<p>Plot number does not exist.</p>"; } exit; // 处理完AJAX请求后终止脚本,避免输出页面其他内容 } ?> </body> </html>
关键修改说明
- 表单提交拦截:通过jQuery监听表单
submit事件,调用e.preventDefault()彻底阻止页面刷新。 - SQL安全优化:将原代码中直接拼接变量的SQL改为PDO参数绑定
bindParam,彻底规避SQL注入风险。 - AJAX动态交互:发送异步请求后,后端通过
ajax_search参数判断是AJAX请求,返回查询结果的HTML,前端填充到Modal后主动打开弹窗。 - Modal内容动态化:清空原Modal body中的PHP代码,改为通过AJAX动态插入结果,避免页面加载时的无效执行逻辑。
内容的提问来源于stack exchange,提问作者Talat Fayyaz
相关产品推荐
相关产品推荐

