Laravel中AJAX提交JSON对象数组仅获CSRF Token的问题求助
问题排查与解决方案
看起来你遇到的核心问题是JSON格式的AJAX请求没有被Laravel正确解析,同时CSRF Token的传递方式也和你设置的请求类型不匹配,导致只有_token被接收到,业务数据丢失。下面分步骤帮你解决:
问题根源分析
- 请求格式不匹配:你设置了
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。 - 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
相关产品推荐
相关产品推荐

