Laravel中AJAX函数无法向控制器提交表单数据求助
问题分析与解决方案
看起来你的AJAX请求无法成功将数据发送到控制器,核心问题在于没有携带Laravel强制要求的CSRF令牌,另外代码里还有一些可以优化的细节,下面一步步来解决:
核心问题:缺失CSRF令牌验证
Laravel默认会对所有POST请求进行CSRF验证,你的表单里虽然用{{csrf_field()}}生成了令牌,但AJAX请求并没有把这个令牌一起发送,导致请求被框架拦截,无法到达控制器。
修改后的AJAX代码
$(document).ready(function(){ $('form.buy-product-form').on('submit', function (e) { e.preventDefault(); // 直接用$(this)指代当前表单,无需重复查找 var $form = $(this); var product_id = $form.attr("id"); $.ajax({ url: $form.attr('action'), type: 'POST', // 携带CSRF令牌 + 商品ID数据 data: { '_token': $form.find('input[name="_token"]').val(), 'id': product_id }, dataType: 'JSON', success: function (response) { // 修复原代码中未定义的url变量问题 window.alert('购买操作已提交!'); // 可根据控制器返回的响应做更多处理,比如console.log(response) }, error: function(xhr){ // 增加错误回调,方便调试请求失败原因 console.log('请求失败:', xhr.responseText); } }); }); });
关键修改点说明
- 携带CSRF令牌:通过
$form.find('input[name="_token"]').val()获取表单内的令牌,加入到AJAX的data参数中,这是Laravel POST请求必须的验证条件。 - 简化DOM操作:
$(this)就是当前触发submit事件的表单元素,不需要用closest("form")重复查找,既简洁又高效。 - 修复回调变量错误:原代码里的
window.alert(url)中url未定义,会导致JS报错,改成实际的提示信息或者使用控制器返回的响应数据。 - 增加错误回调:方便你快速排查请求失败的具体原因(比如令牌验证不通过、路由匹配错误等)。
额外优化建议
- 控制器返回标准JSON响应:确保控制器方法最后返回JSON格式的响应,匹配AJAX的
dataType: 'JSON'要求:
public function buyProduct($university_code, $product_id){ $player = Player::where('user_id', Auth::user()->id)->first(); $product = Product::where('id', $product_id)->first(); $totalPrice = $product->quantity_available * $product->price; // 这里添加你的业务逻辑(比如扣减库存、创建订单记录等) // 返回JSON格式的响应 return response()->json([ 'status' => 'success', 'message' => '购买完成', 'total_price' => $totalPrice ]); }
- 使用命名路由避免硬编码路径:建议给路由设置名称,这样在表单和AJAX里可以用
route()函数生成URL,减少路径错误:
// web.php中的路由定义 Route::post('/{university_code}/buy-product/{product_id}', [ProductController::class, 'buyProduct'])->name('product.buy');
表单的action可以改成:
<form class="buy-product-form" id="{{$product->id}}" action="{{route('product.buy', ['university_code' => 'UoE', 'product_id' => $product->id])}}" method="POST"> {{csrf_field()}} <button class="pull-right btn btn-primary">BUY NOW</button> </form>
这样修改后,你的AJAX请求应该就能正常携带数据并到达控制器了。
内容的提问来源于stack exchange,提问作者Hamish Gibson
相关产品推荐
相关产品推荐

