AJAX PHP
服务器交互:实时搜索 (概念示例)
Section titled “服务器交互:实时搜索 (概念示例)”异步 JavaScript 对于创建交互式用户体验非常强大,例如在用户输入时提供实时搜索建议。
本示例演示了使用 Fetch API 的客户端 JavaScript 以及概念性的服务器端部分(这里通过简单的 PHP 和 Node.js/Express 代码片段表示)。
实时搜索示例
Section titled “实时搜索示例”这演示了当用户在输入字段中输入字符时,网页如何与服务器端点通信以获取建议。
HTML 结构:
Section titled “HTML 结构:”<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>客户端 JavaScript (使用 Fetch):
Section titled “客户端 JavaScript (使用 Fetch):”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, "<").replace(/>/g, ">") ); 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 毫秒后等待});客户端代码解释:
Section titled “客户端代码解释:”- 事件监听器: 向文本字段附加了一个
input事件监听器。 - 防抖 (Debouncing):
setTimeout机制防止在每次按键时都发送请求。 showHint函数: 处理异步逻辑。- 输入检查: 如果输入为空,则清除建议。
- 反馈: 显示“正在搜索…”。
- Fetch 请求: 向服务器端点(例如,
get_suggestions.php或/api/suggestions)发起一个 GET 请求,将用户输入作为q参数。 - 错误处理: 使用
try…catch并检查response.ok。 - JSON 解析: 解析预期的 JSON 数组响应。
- 显示结果: 使用建议或“无建议”更新
txtHintspan,包括基本清理。
概念性服务器端点
Section titled “概念性服务器端点”客户端代码需要对应的服务器端点。下面是 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 正在监听于});重要提示: 这些服务器端示例高度简化。实际应用必须实现健壮的输入验证、清理、适当的错误处理、高效的数据库交互和安全措施(如速率限制)。