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
相关产品推荐
相关产品推荐

