Bootstrap Typeahead结合AJAX/PHP/MySQL无下拉提示问题排查
问题排查:Bootstrap Typeahead 下拉建议不显示(后台已返回数据)
我遇到一个问题:后台接口已经能正常返回数据,浏览器控制台和网络面板都能看到返回的JSON数组,但文本框下方没有出现类似谷歌的下拉建议列表。附上我的前后端代码,请求帮忙排查问题:
前端代码
<!DOCTYPE html> <html> <head> <title>Webslesson Tutorial | Autocomplete Textbox using Bootstrap Typehead with Ajax PHP</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> </head> <body> <br /><br /> <div class="container" style="width:600px;"> <h2 align="center">Autocomplete Textbox using Bootstrap Typeahead with Ajax PHP</h2> <br /><br /> <label>Search Country</label> <input type="text" name="country" id="country" class="form-control input-lg" autocomplete="off" placeholder="Type Country Name" /> </div> </body> </html> <script> $(document).ready(function() { $('#country').typeahead({ source: function(query, result) { $.ajax({ url: "autoselect_jquery2.php", method: "POST", data: { query: query }, dataType: "json", success: function(data) { result($.map(data, function(item) { return item; })); } }) } }); }); </script>
后台PHP代码(autoselect_jquery2.php)
<?php include 'database.php'; if (isset($_POST['query'])) { $search_query = mysqli_real_escape_string($_POST["query"]); $query = "SELECT * FROM transporter WHERE email LIKE '%".$search_query."%' LIMIT 12"; $result = mysqli_query($link, $query); $data = array(); if(mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_assoc($result)) { $data[] = $row["email"]; } echo json_encode($data); } } ?>
排查与解决步骤
1. 先检查控制台是否有隐藏的JS错误
虽然你能看到接口返回数据,但很可能存在JavaScript错误导致Typeahead无法渲染下拉框:
- 打开浏览器控制台(F12 → Console标签),查看是否有类似
$ is not defined(jQuery未加载)或$.fn.typeahead is not a function(Typeahead插件未加载)的报错; - 确认你的CDN资源是否能正常访问:可以直接在浏览器地址栏输入jQuery/Typeahead的CDN链接,看是否能打开对应的文件。
2. 确保返回数据的Content-Type正确
Typeahead依赖正确的JSON格式解析,你的PHP代码没有指定响应头,可能导致jQuery无法正确识别返回数据:
在PHP代码的echo json_encode($data);之前添加:
header('Content-Type: application/json');
3. 简化并完善Typeahead配置
你的初始化代码可以做两处优化,排除不必要的处理:
- 去掉多余的
$.map:因为后台返回的已经是字符串数组,直接传递给result即可; - 添加
minLength配置,确保输入足够字符触发下拉:
$(document).ready(function() { $('#country').typeahead({ minLength: 1, // 输入1个字符就触发下拉 source: function(query, result) { $.ajax({ url: "autoselect_jquery2.php", method: "POST", data: { query: query }, dataType: "json", success: function(data) { result(data); // 直接传递数组即可 } }) } }); });
4. 检查下拉框是否被样式隐藏
有时候下拉框已经生成,但被CSS覆盖导致不可见:
- 输入触发字符后,打开元素检查器(F12 → Elements标签),查找是否存在
class="typeahead dropdown-menu"的元素; - 如果存在,检查它的
display、opacity、z-index属性是否正常,是否被其他元素遮挡。
5. 测试静态数据是否正常显示
先绕过AJAX,用静态数据测试Typeahead是否能正常工作:
$('#country').typeahead({ minLength: 1, source: ["test1@example.com", "test2@example.com", "test3@example.com"] });
如果静态数据能显示,说明问题出在AJAX请求或数据处理环节;如果还是不显示,说明Typeahead的加载或初始化有问题。
额外建议:优化PHP代码的安全性
你的PHP代码虽然用了mysqli_real_escape_string,但更推荐用预处理语句彻底防止SQL注入:
<?php include 'database.php'; if (isset($_POST['query'])) { $search_query = "%".$_POST["query"]."%"; $query = "SELECT email FROM transporter WHERE email LIKE ? LIMIT 12"; $stmt = mysqli_prepare($link, $query); mysqli_stmt_bind_param($stmt, "s", $search_query); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $data = array(); if(mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_assoc($result)) { $data[] = $row["email"]; } } header('Content-Type: application/json'); echo json_encode($data); } ?>
内容的提问来源于stack exchange,提问作者vishal sharma
相关产品推荐
相关产品推荐

