PHP同页实现点击加载更多 AJAX追加API数据到HTML表格
实现「点击加载更多无刷新追加API数据到HTML表格」方案
原有代码核心问题
- 表格渲染逻辑错误:循环输出数据时未给单条数据包裹独立的
<tr>标签,所有单元格会挤在同一行 - 依赖库版本错误:使用的jQuery slim版本移除了AJAX相关方法,无法正常发送异步请求
- 接口返回格式不规范:后端用
print_r输出数据,不是前端可直接解析的标准JSON格式 - 分页逻辑缺失:没有持久化保存上一次拉取的最后一条数据ID,无法正确请求下一页内容
- AJAX回调逻辑为空:请求成功后没有执行DOM追加操作,自然看不到数据更新
完整实现代码
1. 列表主页面(index.php)
负责初始渲染第一页表格、绑定加载更多按钮的点击事件
<?php // 初始拉取第一页数据 $apiurl = 'https://mywebsiteapi.com'; $postParams = "name=test"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiurl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G973N Build/PPR1.190810.011)" ]); curl_setopt($ch, CURLOPT_POSTFIELDS, $postParams); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); curl_close($ch); $list = $result['t'] ?? []; $initialData = []; $lastId = 0; if (!empty($list[0]['ID'])) { foreach ($list as $item) { $initialData[] = [ 'name' => $item['Name'], 'phone' => $item['Phone'] ]; } $lastId = end($list)['ID']; } ?> <!-- 引入完整版jQuery,不要用slim版 --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <table border="1" cellpadding="8" cellspacing="0"> <thead> <tr> <th>姓名</th> <th>手机号</th> </tr> </thead> <tbody id="dataTbody"> <?php foreach ($initialData as $row): ?> <tr> <td><?php echo $row['name'] ?></td> <td><?php echo $row['phone'] ?></td> </tr> <?php endforeach; ?> </tbody> </table> <br> <button id="loadMoreBtn" style="padding: 8px 16px; cursor: pointer;">加载更多数据</button> <script> // 全局保存当前最后一条数据的ID,作为下一次请求的分页游标 let lastId = <?php echo $lastId; ?>; $('#loadMoreBtn').on('click', function() { const btn = $(this); // 请求过程中禁用按钮,防止重复点击 btn.prop('disabled', true).text('加载中...'); $.ajax({ type: 'POST', url: 'load_more.php', data: {last_id: lastId}, dataType: 'json', success: function(res) { if (res.code !== 200) { alert(res.msg || '加载失败'); btn.prop('disabled', false).text('加载更多数据'); return; } // 没有更多数据时直接禁用按钮 if (res.no_more) { btn.text('没有更多数据了'); return; } // 循环拼接新的数据行,追加到表格末尾 let html = ''; res.data.forEach(item => { html += `<tr> <td>${item.name}</td> <td>${item.phone}</td> </tr>`; }); $('#dataTbody').append(html); // 更新分页游标 lastId = res.last_id; btn.prop('disabled', false).text('加载更多数据'); }, error: function() { alert('网络请求错误,请重试'); btn.prop('disabled', false).text('加载更多数据'); } }) }) </script>
2. 异步加载接口(load_more.php)
负责接收前端传的分页游标,请求自有API拉取下一页数据,返回标准JSON格式
<?php // 设置返回格式为JSON header('Content-Type: application/json'); $lastId = $_POST['last_id'] ?? 0; // 拼接待传给自有API的参数,把lastId传过去实现分页 $apiurl = 'https://mywebsiteapi.com'; $postParams = "name=test&last_id=" . $lastId; // 这里根据你的API实际要求调整分页参数名 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiurl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G973N Build/PPR1.190810.011)" ]); curl_setopt($ch, CURLOPT_POSTFIELDS, $postParams); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $apiResult = json_decode(curl_exec($ch), true); curl_close($ch); $list = $apiResult['t'] ?? []; // 接口返回空数据代表没有更多内容 if (empty($list) || empty($list[0]['ID'])) { echo json_encode([ 'code' => 200, 'no_more' => true ]); exit; } // 处理返回数据 $formatData = []; foreach ($list as $item) { $formatData[] = [ 'name' => $item['Name'], 'phone' => $item['Phone'] ]; } $newLastId = end($list)['ID']; echo json_encode([ 'code' => 200, 'no_more' => false, 'data' => $formatData, 'last_id' => $newLastId ]); exit; ?>
关键说明
- 分页参数
last_id需要和你的自有API实际要求的参数名保持一致,如果API是用page、offset分页,对应修改参数即可 - 不要在接口文件里输出任何除了JSON以外的内容(比如echo调试语句、HTML标签),否则会导致前端解析失败
- 如果需要支持搜索、筛选功能,只需要把对应的筛选参数和lastId一起传给后端接口即可,逻辑和加载更多一致
- 初始加载和加载更多的curl请求配置可以抽成公共函数,避免重复写代码
内容的提问来源于stack exchange,提问作者amr salah
相关产品推荐
相关产品推荐

