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

如何通过DataTables Ajax向Laravel控制器正确传递ID获取产品变体

问题:Laravel中DataTables服务器端请求404,ID传递不符合路由要求

要实现通过产品ID获取变体并使用DataTables服务器端展示,但请求返回404,原因是ID以查询参数传递,而路由要求ID在URL路径中。相关代码如下:

DataTables初始化代码

$("#productVariants").DataTable({
    responsive: true,
    lengthChange: false,
    autoWidth: false,
    dom: "Bfrtip",
    buttons: ["pageLength", "copy", "csv", "excel", "pdf", "print"],
    processing: true,
    serverSide: true,
    ajax: {
        url: "/shop/product/variants/",
        type: "GET",
        'data': {
            id: $("#productVariants").attr("rel"),
        },
    },
    columns: [
        { data: "description", name: "description" },
        { data: "cost", name: "cost" },
        { data: "status", name: "status" },
        { data: "id",
            render: function(data, type, row) {
                return (
                    '<div class="dropdown dropdown-action">' +
                    '<a href="#" class="action-icon dropdown-toggle"'+ 
                   'data-toggle="dropdown" aria-expanded="false">'+ 
                   '<i class="fa fa-ellipsis-v"></i></a>' +
                    '<div class="dropdown-menu dropdown-menu-left">' +
                    '<a href="/shop/product/variants/' +
                    data +
                    '/edit"' +
                    'class="dropdown-item" data-toggle="tooltip"' +
                    'data-placement="top" title="Edit">' +
                    '<i class="fa fa-pen"' +
                    'aria-hidden="true"></i> Edit</a>' +
                    '<a rel="' +
                    data +
                    '" rel1="delete" href="javascript:"' +
                    'class="dropdown-item deleteProductVariant"' +
                    'data-toggle="tooltip" data-placement="top" title="Delete">' +
                   '<i class="fa fa-trash"></i> Delete</a>' +
                    "</div>" +
                    "</div>"
                );
            },
            name: "Action",
            orderable: false,
            searchable: false,
            printable: false
        }
    ],
    stateSave: true,
    bDestroy: true
});

路由配置

Route::get('/variants/{id}', [ProductController::class, 'variants']);

控制器代码

if ($request->ajax()) {
    $data = ProductVariant::join('statuses','product_variants.status_id',
  'statuses.id')->join('variant_types','product_variants.variant_type_id',
  'variant_types.id')->join('variant_categories','variant_types.cat_id',
  'variant_categories.id')->select('product_variants.id As id',
  'variant_types.name As name','product_variants.cost As cost',
  'variant_categories.name As category', 'statuses.name As status')
  ->where(['product_variants.p_id'=>$id])->get();
        return Datatables::of($data)->addIndexColumn()->make(true);
}

错误请求URL

GET http://127.0.0.1:8000/shop/product/variants/?draw=1&columns%5B0%5D%5Bdata%5D=category&columns%5B0%5D%5Bname%5D=category&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=name&columns%5B1%5D%5Bname%5D=name&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=cost&columns%5B2%5D%5Bname%5D=cost&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=status&columns%5B3%5D%5Bname%5D=status&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=id&columns%5B4%5D%5Bname%5D=Action&columns%5B4%5D%5Bsearchable%5D=false&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&id=742&_=1677158506437 404 (Not Found)

---

# 解决方案

核心问题是DataTables的请求URL未将ID嵌入路径,而是作为查询参数传递,与路由规则不匹配。需修改以下两处:

## 1. 修改DataTables的ajax配置
把ID直接拼接进URL路径,移除`data`中的ID参数:
```javascript
ajax: {
    url: "/shop/product/variants/" + $("#productVariants").attr("rel"),
    type: "GET"
},

修改后请求URL会变为/shop/product/variants/742(假设ID为742),完全匹配路由/variants/{id}的规则。

2. 确保控制器正确接收路由参数

控制器方法需声明接收路由中的$id参数,同时规范查询逻辑的写法:

public function variants(Request $request, $id) {
    if ($request->ajax()) {
        $data = ProductVariant::join('statuses','product_variants.status_id', 'statuses.id')
            ->join('variant_types','product_variants.variant_type_id', 'variant_types.id')
            ->join('variant_categories','variant_types.cat_id', 'variant_categories.id')
            ->select(
                'product_variants.id As id',
                'variant_types.name As name',
                'product_variants.cost As cost',
                'variant_categories.name As category',
                'statuses.name As status'
            )
            ->where('product_variants.p_id', $id)
            ->get();
            
        return Datatables::of($data)->addIndexColumn()->make(true);
    }
    
    // 非AJAX请求的处理逻辑(按需添加)
    return view(...);
}

额外修正点

当前DataTables列配置中的description字段,与控制器查询返回的category/name字段不匹配,需修改列配置对应正确字段,否则表格会显示空数据:

columns: [
    { data: "category", name: "category" },
    { data: "name", name: "name" },
    { data: "cost", name: "cost" },
    { data: "status", name: "status" },
    // 操作列保持不变
]

内容的提问来源于stack exchange,提问作者The Only Smart Boy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:39:37