使用 fetch + JSON 接口可避免 XMLHttpRequest 和过时函数;关键在于前后端数据结构对齐、分页参数严格校验(如 $page = max(1, min((int)$_GET['page'], 999)))、错误统一返回 JSON 格式(如 {"error": "invalid page"}),PHP 端需清空缓冲、设置 header('Content-Type: application/json')、仅输出合法 JSON;前端用 new URL 构造请求、禁用重复点击、捕获网络与解析异常;大数据量时应改用游标分页(如 WHERE id < ? ORDER BY id DESC LIMIT 11),并确保主键有索引且单调。

直接用 fetch + JSON 接口就能跑通,不需要手写 XMLHttpRequest 或依赖过时的 mysql_* 函数;关键在于前后端数据结构对齐、分页参数校验到位、错误边界处理不漏。
PHP 后端必须返回标准 JSON 结构
很多失败案例卡在后端返回的是 HTML 片段或混合输出(比如 echo 了调试信息),前端 fetch 拿到后无法 response.json()。必须确保 PHP 脚本只输出合法 JSON:
- 开头清空输出缓冲:
ob_end_clean(),避免 BOM 或空格污染 JSON - 设置响应头:
header('Content-Type: application/json; charset=utf-8') - 统一返回结构,例如:
{"data": [...], "pagination": {"total": 127, "page": 2, "per_page": 10, "pages": 13}} - 出错时不 echo 错误信息,而是返回带
"error"字段的 JSON,比如{"error": "invalid page"}
前端 fetch 请求要带 page 参数并处理 loading 状态
点击页码时,不能只改 URL 或拼接 ?page=3 就发请求,容易忽略当前状态导致重复点击、请求乱序。实际操作中应:
- 禁用点击中的页码链接:
el.disabled = true或加loadingclass - URL 构造用
new URL()更安全,避免手动拼接出错:const url = new URL('/api/list.php'); url.searchParams.set('page', 3); - 捕获网络异常和 JSON 解析失败:
try { await res.json() }外层包catch (e) { console.error(e) } - 成功后更新内容区域前,先清空旧 DOM 或替换整个容器 innerHTML,避免残留
分页参数校验必须在 PHP 端做,不能信前端传来的任何值
常见漏洞是直接用 $_GET['page'] 做计算,导致 SQL 注入或崩溃。正确做法是:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
立即学习“PHP免费学习笔记(深入)”;
- 强制转整型并限定范围:
$page = max(1, min((int)$_GET['page'], 999)) - 每页条数也需限制:
$per_page = in_array($_GET['limit'] ?? 10, [5,10,20,50]) ? (int)$_GET['limit'] : 10 - OFFSET 计算必须基于校验后值:
$offset = ($page - 1) * $per_page,再传给 PDO 的bindValue - 总数查询必须独立执行(不要用
SQL_CALC_FOUND_ROWS,已废弃),用SELECT COUNT(*)子查询或单独语句
游标分页更适合大数据量,但需改写 SQL 和前端逻辑
当总记录超 10 万、LIMIT 100000, 10 明显变慢时,OFFSET 分页会拖垮性能。这时应切换为游标分页:
- 后端 SQL 改为:
SELECT * FROM articles WHERE id < ? ORDER BY id DESC LIMIT 11(假设用id作游标) - 前端不再传
page,而是传上一页最后一条的id,如cursor=12345 - 返回数据时,如果查出 11 条,就把第 11 条的
id作为下一页的next_cursor字段返回 - 前端渲染只显示前 10 条,隐藏第 11 条,但保留其
id用于下次请求
这个方案跳过了页码概念,但要求主键或时间字段有索引、单调、无删除空洞——这些约束容易被忽略,上线前务必验证索引是否生效。


















