Skip to content

AJAX PHP

服务器交互:实时搜索 (概念示例)

Section titled “服务器交互:实时搜索 (概念示例)”

异步 JavaScript 对于创建交互式用户体验非常强大,例如在用户输入时提供实时搜索建议。

本示例演示了使用 Fetch API 的客户端 JavaScript 以及概念性的服务器端部分(这里通过简单的 PHP 和 Node.js/Express 代码片段表示)。

这演示了当用户在输入字段中输入字符时,网页如何与服务器端点通信以获取建议。

<p>**开始输入姓名:**</p>
<form onsubmit="return false;"> <!-- 阻止默认提交 -->
<label for="txtName">姓名:</label>
<input type="text" id="txtName" name="name" autocomplete="off">
</form>
<p>建议: <span id="txtHint"></span></p>
<p><small>服务器端点: /api/suggestions (PHP: get_suggestions.php)</small></p>
const nameInput = document.getElementById('txtName');
const hintSpan = document.getElementById('txtHint');
let debounceTimer; // 用于请求防抖
async function showHint(query) {
// 基本验证
if (query.length === 0) {
hintSpan.innerHTML = '';
return;
}
hintSpan.innerHTML = '<i>正在搜索...</i>'; // 提供反馈
try {
// 构造 URL 并带上查询参数
// 如果使用 PHP 示例后端,请使用 'get_suggestions.php'
const url = `get_suggestions.php?q=${encodeURIComponent(query)}`;
// 或者如果使用 Node.js 示例,请使用 '/api/suggestions?q=...'
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Server error: ${response.status}`); // 服务器错误
}
const suggestions = await response.json(); // 预期是 JSON 字符串数组
if (suggestions.length > 0) {
// 在显示前对建议进行清理 (基本示例)
const safeSuggestions = suggestions.map(s =>
String(s).replace(/</g, "&lt;").replace(/>/g, "&gt;")
);
hintSpan.innerHTML = safeSuggestions.join(', '); // 连接并显示建议
} else {
hintSpan.innerHTML = '无建议'; // 无建议
}
} catch (error) {
console.error('Error fetching suggestions:', error); // 获取建议出错
hintSpan.innerHTML = '<i style="color:red;">获取建议出错</i>'; // 获取建议出错 (红色)
}
}
nameInput.addEventListener('input', (event) => {
const query = event.target.value;
// 防抖: 清除之前的计时器并设置新的
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
showHint(query);
}, 300); // 用户停止输入 300 毫秒后等待
});
  • 事件监听器: 向文本字段附加了一个 input 事件监听器。
  • 防抖 (Debouncing): setTimeout 机制防止在每次按键时都发送请求。
  • showHint 函数: 处理异步逻辑。
  • 输入检查: 如果输入为空,则清除建议。
  • 反馈: 显示“正在搜索…”。
  • Fetch 请求: 向服务器端点(例如,get_suggestions.php 或 /api/suggestions)发起一个 GET 请求,将用户输入作为 q 参数。
  • 错误处理: 使用 try…catch 并检查 response.ok。
  • JSON 解析: 解析预期的 JSON 数组响应。
  • 显示结果: 使用建议或“无建议”更新 txtHint span,包括基本清理。

客户端代码需要对应的服务器端点。下面是 PHP 和 Node.js 中的概念示例。

概念性 PHP 示例 (get_suggestions.php):

Section titled “概念性 PHP 示例 (get_suggestions.php):”
<?php
// --- 服务器端 (PHP - 例如, get_suggestions.php) ---
// 示例数据 (在实际应用中请替换为数据库查询)
$names = [
"Anna", "Amanda", "Alice", "Bob", "Brittany", "Barbara",
"Charles", "Cindy", "Cinderella", "David", "Diana", "Doris",
"Eva", "Elizabeth", "Ellen", "Fiona", "Gunda", "Hege", // 等等。
];
// 从 URL 获取 'q' 参数,略微清理
$query = isset($_GET['q']) ? trim(strtolower($_GET['q'])) : '';
$suggestions = [];
// 仅当查询不为空时才搜索
if (!empty($query)) {
foreach ($names as $name) {
// 简单的、不区分大小写的开头匹配检查
// 如果需要处理多字节字符,请使用 mb_strtolower 和 mb_strpos 以确保安全
if (strpos(strtolower($name), $query) === 0) {
$suggestions[] = $name; // 将匹配的姓名添加到建议数组
}
}
}
// 设置头部,指示 JSON 响应
// 这对于客户端的 response.json() 正确工作至关重要
header('Content-Type: application/json');
// 如果需要防止结果缓存 (特别是对于动态数据)
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // 过去日期
// 将数组编码为 JSON 并输出
echo json_encode($suggestions);
?>

PHP 解释:

  • 数据源: 使用一个简单的数组 $names。请将其替换为数据库查询。
  • 获取输入: 从 $_GET 超全局变量中检索 q 参数。
  • 搜索逻辑: 遍历姓名列表并查找匹配项(不区分大小写的开头匹配)。
  • 设置头部: 关键地设置 Content-Type: application/json,以便浏览器知道如何解释响应。Cache-control 头部对于动态端点通常很有用。
  • 输出 JSON: 使用 json_encode() 将 PHP 数组 $suggestions 转换为 JSON 字符串,并使用 echo 将其作为响应体输出。

概念性 Node.js/Express 示例 (/api/suggestions):

Section titled “概念性 Node.js/Express 示例 (/api/suggestions):”
// --- 服务器端 (使用 Express 的 Node.js) ---
const express = require('express');
const app = express();
const port = 3000;
// 示例数据 (在实际应用中,这通常来自数据库)
const names = [
"Anna", "Amanda", "Alice", "Bob", "Brittany", "Barbara",
"Charles", "Cindy", "Cinderella", "David", "Diana", "Doris", // ... 更多姓名
];
app.get('/api/suggestions', (req, res) => {
const query = (req.query.q || '').toLowerCase(); // 获取 'q' 查询参数
let suggestions = [];
if (query.length > 0) {
suggestions = names.filter(name =>
name.toLowerCase().startsWith(query)
);
}
// Express 的 res.json() 会自动设置 Content-Type 并进行字符串化
res.json(suggestions);
});
app.listen(port, () => {
console.log(`建议 API 正在监听于 http://localhost:${port}`); // 建议 API 正在监听于
});

重要提示: 这些服务器端示例高度简化。实际应用必须实现健壮的输入验证、清理、适当的错误处理、高效的数据库交互和安全措施(如速率限制)。