You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用AJAX响应填充HTML表格?Laravel无刷新更新问题

问题:Laravel Blade页面无刷新更新表格内容失败

我有个Laravel Blade视图页面,想实现无需刷新页面就能更新内容。Blade.php能正常从MySQL取数据,但AJAX/JavaScript代码跑不起来。我有C#开发背景,从没接触过AJAX/JavaScript/PHP,现在遇到的问题是AJAX调用返回的内容看起来像JSON,但没法正确识别访问内部元素。控制器能正常返回数据,我要实现的是:每5秒从数据库获取新数据,更新现有表格(有新数据时更新)。


视图代码(view.blade.php)

<table class="table custom--table" id="mainTable">
  <thead>
    <tr>
        <th>@lang('ID')</th>
        <th>@lang('Name')</th>
        <th>@lang('Date')</th>
        <th>@lang('Details')</th>
    </tr>
  </thead>
  <tbody>
    @forelse($items as $data)
        <tr>
            <td data-label="@lang('ID')">
                {{ $loop->index + 1 }}
            </td>
            <td data-label="@lang('Name')">{{ $data->name }}</td>
            <td data-label="@lang('Date')">{{ $data->created_at }}</td>
            <td id="detailz" data-label="@lang('Details')">{{ $data->details }}</td>
        </tr>
    @empty
        <tr>
            <td colspan="100%" class="text-center justify-content-center">@lang('No data.')</td>
        </tr>
    @endforelse
  </tbody>
</table>

失效的AJAX代码

function updatePost() {
setInterval(function() {
    $.ajax({
        type: "GET",
        url: "{{route('user.posts.update')}}", // 路由正常
        success: function( response ){

            $('#mainTable')[0].reset();
             $("tbody").html("");
             $.each(response, function( index, value ) {
                var row = $("<tr><td>"
                            + value.name + "</td><td>"
                            + value.details + "</td><td>"
                            + value.created_at + "</td><td>");

                $("tbody").append(row);
            });

        },
        error: function( response ){
            console.log("Error!");
            console.log(response);
        }
    });
}, 5000); // 每5秒执行一次
}

控制器代码(controller.php)

public function postUpdate(){
    $pageTitle = 'Post Update';
    $data = DataHistory::where('user_id', Auth::user()->id)->latest()->paginate(getPaginate());
    return response()->json($data);
}

返回的数据示例

{
    "current_page":1,
    "data":[{
            "id":34,
            "user_id":1,
            "name":"RANDOM NAME DATA",
            "details":"RANDOM DETAILS",
            "created_at":"2022-11-16T15:02:56.000000Z"
        },{
            "id":32,
            "user_id":1,
            "name":"RANDOM NAME DATA 2",
            "details":"RANDOM DETAILS 2",
            "created_at":"2022-11-16T10:19:29.000000Z"
        }],
    "first_page_url":"https://xyz.com/posts/update/?page=1",
    "from":1,
    "last_page":1,
    "last_page_url":"https://xyz.com/posts/update/?page=1",
    "links":[{
            "url":null,
            "label":"&laquo; Previous",
            "active":false
        },{
            "url":"https://xyz.com/posts/update/?page=1",
            "label":"1",
            "active":true
        },{
            "url":null,
            "label":"Next &raquo;",
            "active":false
        }],
    "next_page_url":null,
    "path":"https://xyz.com/posts/update/",
    "per_page":20,
    "prev_page_url":null,
    "to":7,
    "total":7
}

解决方案

你的方向是对的,问题出在几个细节上:

  1. 数据访问层级错误:控制器返回的是Laravel分页对象的JSON,实际业务数据在response.data数组里,你现在直接遍历整个response,会把分页的元数据(比如current_page)也当成数据处理,自然取不到name等属性。
  2. 表格重置方法错误:$('#mainTable')[0].reset()是表单的专属重置方法,表格没有这个方法,直接删除该行即可。
  3. HTML结构不完整:拼接的<tr>标签最后缺少闭合的</tr>,会导致DOM结构异常。
  4. 重复ID问题:Blade循环里给<td>加了id="detailz",多个行重复ID违反HTML规范,改成class或者直接去掉。

修正后的AJAX代码:

function updatePost() {
    setInterval(function() {
        $.ajax({
            type: "GET",
            url: "{{route('user.posts.update')}}",
            dataType: "json", // 明确指定返回类型为JSON,避免解析歧义
            success: function( response ){
                $("tbody").html("");
                // 遍历response中的业务数据数组
                $.each(response.data, function( index, value ) {
                    // 补全HTML结构,修正ID为class,保持序号逻辑和Blade一致
                    var row = $(`<tr>
                        <td data-label="@lang('ID')">${index + 1}</td>
                        <td data-label="@lang('Name')">${value.name}</td>
                        <td data-label="@lang('Date')">${value.created_at}</td>
                        <td class="detailz" data-label="@lang('Details')">${value.details}</td>
                    </tr>`);

                    $("tbody").append(row);
                });

                // 无数据时显示空状态
                if(response.data.length === 0) {
                    $("tbody").html('<tr><td colspan="100%" class="text-center justify-content-center">@lang("No data.")</td></tr>');
                }
            },
            error: function( xhr ){
                console.log("请求错误:", xhr.responseText);
            }
        });
    }, 5000);
}

// 页面加载完成后启动定时任务
$(document).ready(function() {
    updatePost();
});

额外优化建议

  • 如果只需要新增数据,不需要每次清空表格,可以记录最后一条数据的id,请求时传给控制器,只返回id大于该值的新数据,减少带宽消耗。
  • 可以给AJAX请求添加loading状态,提升用户体验。

内容的提问来源于stack exchange,提问作者CodeEmpires

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:40:41