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

Laravel中AJAX提交JSON对象数组仅获CSRF Token的问题求助

问题排查与解决方案

看起来你遇到的核心问题是JSON格式的AJAX请求没有被Laravel正确解析,同时CSRF Token的传递方式也和你设置的请求类型不匹配,导致只有_token被接收到,业务数据丢失。下面分步骤帮你解决:

问题根源分析

  1. 请求格式不匹配:你设置了contentType: 'application/json',但发送的data是{dataInput : JSON.stringify(objArr)}——jQuery会把这个对象自动编码成application/x-www-form-urlencoded格式(比如dataInput=%5B%7B%22name%22%3A...%7D%5D),和你声明的JSON格式冲突,Laravel无法识别这是JSON数据,自然拿不到dataInput。
  2. CSRF Token传递矛盾:当发送JSON请求时,表单里的_token字段不会被自动包含到请求体中(因为请求体是纯JSON字符串),不过你现在能拿到_token,是因为jQuery自动把表单数据拼到了请求里,但这和JSON格式的请求逻辑矛盾。

方案一:使用纯JSON格式发送请求(推荐复杂结构场景)

1. 先在Blade页面添加CSRF Meta标签(方便AJAX获取)

在createPage.blade.php的<head>里加上:

<meta name="csrf-token" content="{{ csrf_token() }}">

2. 修改JavaScript发送逻辑

调整AJAX的headers和data部分,确保发送的是纯JSON字符串:

$(function(){
    $('#my-form').submit(function(e){
        let elements = document.querySelectorAll("#my-form input[type=text]");
        let nameContainer = [], priceContainer = [], objArr = [];
        
        // 收集输入值的逻辑不变
        for (let i = 0, element; element = elements[i++];) {
            if(element.type === "text" && element.value){
                if(element.className === "goodName"){
                    nameContainer.push(element.value);
                } else {
                    priceContainer.push(element.value);
                }
            }
        }
        
        // 构建对象数组(简化写法)
        for(let i = 0; i < nameContainer.length; i++){
            objArr.push({
                name: nameContainer[i],
                price: priceContainer[i]
            });
        }

        $.ajax({
            type : 'POST',
            url : '/invoices/submitInvoice',
            // 把CSRF Token放到请求头里(JSON请求的标准做法)
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            // 将整个数据对象转成JSON字符串发送
            data : JSON.stringify({ dataInput: objArr }),
            contentType: 'application/json; charset=utf-8',
            dataType : 'json',
            success: function(Response){
                console.log("daw",Response);
            },
            // 新增错误处理,方便调试
            error: function(xhr){
                console.error('请求失败:', xhr.responseText);
            }
        });
        e.preventDefault();
    });
});

3. 修改控制器解析JSON数据

因为请求体是纯JSON,需要用Laravel的json()方法或者解析原始内容来获取数据:

public function invoiceCreate(Request $request){
    // 方式1:直接通过json()方法获取指定字段
    $data = $request->json('dataInput');
    dd($data);

    // 方式2:解析整个请求的原始JSON内容
    // $rawData = json_decode($request->getContent(), true);
    // dd($rawData);
}

方案二:使用表单编码格式发送(适合简单数组场景)

如果你的数据结构不复杂,可以不用JSON格式,直接用默认的表单编码,这样更简单:

1. 修改JavaScript代码

去掉contentType设置,直接发送对象,jQuery会自动处理表单编码,同时自动带上表单里的_token:

$(function(){
    $('#my-form').submit(function(e){
        // (收集数据的逻辑和之前一样,略)
        
        $.ajax({
            type : 'POST',
            url : '/invoices/submitInvoice',
            // 直接发送对象,jQuery自动编码为表单格式
            data : { 
                dataInput: objArr 
                // _token会自动从表单中获取,不用手动加
            },
            dataType : 'json',
            success: function(Response){
                console.log("daw",Response);
            }
        });
        e.preventDefault();
    });
});

2. 控制器获取数据

直接用常规的请求方法即可:

public function invoiceCreate(Request $request){
    $data = $request->get('dataInput');
    dd($data);
}

额外调试建议

  • 打开浏览器的开发者工具(F12),在Network标签下查看发送的请求:检查Request Payload(JSON请求)或Form Data(表单请求)里是否包含你的dataInput数据。
  • 查看请求头里的Content-Type是否和你设置的一致,确保没有冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:32:42