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

Laravel中使用Yajra DataTable时视图页面显示原始JSON数据的问题求助

Laravel中使用Yajra DataTable时视图页面显示原始JSON数据的问题求助

我最近在Laravel项目里集成Yajra DataTable,本来想实现一个带增删改查按钮的动态表格,结果折腾了半天,视图页面直接显示原始的JSON数据,完全没渲染成预期的表格。已经安装了依赖包,代码也按文档写了,但就是不对,求各位大佬帮忙看看问题出在哪!

环境与依赖

已经通过Composer安装了Yajra DataTable包:

composer require yajra/laravel-datatables-oracle

控制器代码(PostController.php)

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use DataTables;
use Illuminate\Http\JsonResponse;
use Exception;

class PostController extends Controller
{
    public function index() {
        try {
            $product = Post::query();
            return Datatables::of($product)
                ->addIndexColumn()
                ->addColumn('action', function($row){
                    $btn = '<a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="View" class="me-1 btn btn-info btn-sm showProduct"><i class="fa-regular fa-eye"></i> View</a>';
                    $btn .= '<a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="Edit" class="edit btn btn-primary btn-sm editProduct"><i class="fa-regular fa-pen-to-square"></i> Edit</a>';
                    $btn .= ' <a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="Delete" class="btn btn-danger btn-sm deleteProduct"><i class="fa-solid fa-trash"></i> Delete</a>';
                    return $btn;
                })
                ->rawColumns(['action'])
                ->make(true);
            
            // 下面这行代码永远不会执行!因为上面已经返回了JSON响应
            return view('temp',compact('product'));
        } catch (Exception $e) {
            return response()->json([
                'status' => 200,
                'message' => $e->getMessage()
            ]);
        }
    }

    public function store(Request $request) {
        // 新增/编辑逻辑(原代码保留)
    }
}

视图代码(temp.blade.php)

<!-- 必须添加CSRF Token标签,否则AJAX请求会报错 -->
<meta name="csrf-token" content="{{ csrf_token() }}">

<!-- 引入依赖CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link href="https://cdn.datatables.net/1.11.4/css/dataTables.bootstrap5.min.css" rel="stylesheet">
<!-- 引入Font Awesome CSS,否则按钮图标不显示 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div class="card-body">
    <table class="table table-bordered data-table">
        <thead>
            <tr>
                <th>No</th>
                <th>Name</th>
                <th>Detail</th>
                <th width="280px">Action</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
</div>

<!-- 引入依赖JS -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.11.4/js/dataTables.bootstrap5.min.js"></script>

<script type="text/javascript">
$(document).ready(function() {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    var table = $('.data-table').DataTable({
        processing: true,
        serverSide: true,
        url: 'posts', // 原URL指向返回JSON的控制器方法
        type: 'GET',
        columns: [
            {data: 'DT_RowIndex', name: 'DT_RowIndex'},
            {data: 'name', name: 'name'},
            {data: 'detail', name: 'detail'},
            {data: 'action', name: 'action', orderable: false, searchable: false},
        ]
    });
});
</script>

路由配置(web.php)

Route::get('posts', [PostController::class, 'index']);
Route::post('posts', [PostController::class, 'store']);

问题现象

访问/posts时,页面直接显示原始JSON数据,完全没有渲染表格:

{
  "draw": 0,
  "recordsTotal": 4,
  "recordsFiltered": 4,
  "data": [
    {
      "id": 1,
      "name": "testte",
      "detail": "test-dsc",
      "status": "1",
      "created_at": null,
      "updated_at": null,
      "action": "\u003Ca href=\"javascript:void(0)\" data-toggle=\"tooltip\" data-id=\"1\" data-original-title=\"View\" class=\"me-1 btn btn-info btn-sm showProduct\"\u003E\u003Ci class=\"fa-regular fa-eye\"\u003E\u003C/i\u003E View\u003C/a\u003E\u003Ca href=\"javascript:void(0)\" data-toggle=\"tooltip\" data-id=\"1\" data-original-title=\"Edit\" class=\"edit btn btn-primary btn-sm editProduct\"\u003E\u003Ci class=\"fa-regular fa-pen-to-square\"\u003E\u003C/i\u003E Edit\u003C/a\u003E \u003Ca href=\"javascript:void(0)\" data-toggle=\"tooltip\" data-id=\"1\" data-original-title=\"Delete\" class=\"btn btn-danger btn-sm deleteProduct\"\u003E\u003Ci class=\"fa-solid fa-trash\"\u003E\u003C/i\u003E Delete\u003C/a\u003E"
    }
  ]
}

问题分析与解决方案

核心问题:控制器逻辑冲突

当前index方法中,先执行了Datatables::make(true),这会直接返回JSON响应,浏览器拿到响应后就会显示JSON,而方法后续的return view永远不会执行——HTTP请求只能返回一个响应,JSON响应已经发送,后续代码全部被跳过。

正确解决方案:拆分视图与AJAX逻辑

把返回视图和处理数据的逻辑拆成两个独立方法,对应不同路由:

1. 更新路由配置(web.php)

// 返回视图的路由
Route::get('posts', [PostController::class, 'index']);
// 处理DataTable AJAX请求的路由
Route::get('posts/data', [PostController::class, 'getPostsData']);
// 新增/编辑路由保持不变
Route::post('posts', [PostController::class, 'store']);

2. 重构PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use DataTables;
use Illuminate\Http\JsonResponse;
use Exception;

class PostController extends Controller
{
    // 仅负责返回视图
    public function index() {
        return view('temp');
    }

    // 专门处理DataTable的AJAX数据请求
    public function getPostsData() {
        try {
            $product = Post::query();
            return Datatables::of($product)
                ->addIndexColumn()
                ->addColumn('action', function($row){
                    $btn = '<a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="View" class="me-1 btn btn-info btn-sm showProduct"><i class="fa-regular fa-eye"></i> View</a>';
                    $btn .= '<a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="Edit" class="edit btn btn-primary btn-sm editProduct"><i class="fa-regular fa-pen-to-square"></i> Edit</a>';
                    $btn .= ' <a href="javascript:void(0)" data-toggle="tooltip" data-id="'.$row->id.'" data-original-title="Delete" class="btn btn-danger btn-sm deleteProduct"><i class="fa-solid fa-trash"></i> Delete</a>';
                    return $btn;
                })
                ->rawColumns(['action'])
                ->make(true);
        } catch (Exception $e) {
            // 错误状态码改为500,符合HTTP规范
            return response()->json([
                'status' => 500,
                'message' => $e->getMessage()
            ]);
        }
    }

    public function store(Request $request) {
        // 原新增/编辑逻辑保留
    }
}

3. 更新视图中的AJAX地址(temp.blade.php)

把DataTable初始化的url指向新的AJAX路由:

var table = $('.data-table').DataTable({
    processing: true,
    serverSide: true,
    url: 'posts/data', // 修改为新的AJAX路由
    type: 'GET',
    columns: [
        {data: 'DT_RowIndex', name: 'DT_RowIndex'},
        {data: 'name', name: 'name'},
        {data: 'detail', name: 'detail'},
        {data: 'action', name: 'action', orderable: false, searchable: false},
    ]
});

验证效果

现在访问/posts,页面会正常渲染表格框架,DataTable会自动通过AJAX请求/posts/data获取数据,最终显示带增删改查按钮的动态表格,不会再显示原始JSON了!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 09:28:04