如何通过AJAX将order_id传递至Laravel控制器
问题描述
在Laravel项目中,我在foreach循环内嵌套表单,试图将按钮的data-order-id="{{ $user->order_id }}"值传递到控制器。目前console.log能正常输出该值,但控制器中获取的order_id变量始终为null,仅OrderStatus参数能正常获取。
相关代码
Blade模板
<form action="{{ route('seller_order_all') }}" id="getID" method="post"> @csrf <div class="col d-flex flex-column toggle-action" id="{{ $user->order_id }}-{{ $user->product_name }}-{{ $user->status }}" style="position: relative; border: 0.5px solid #8D8D8D; padding-left: 5px; margin-top: 8px; margin-left: -92px; width: 124.075px; background: #ffffff;"> @if ($user->status == 'To Pay') <button class="btn to-pay-button" name="OrderStatus" value="To Pay" type="submit" data-order-id="{{ $user->order_id }}" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">To Ship</button> @endif @if ($user->status == 'To Ship') <button class="btn to-pay-button" name="OrderStatus" value="To Ship" type="submit" data-order-id="{{ $user->order_id }}" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Shipping</button> @endif @if ($user->status == 'Shipping') <button class="btn to-pay-button" type="submit" name="OrderStatus" value="Completed" data-order-id="{{ $user->order_id }}" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Completed</button> <button class="btn to-pay-button" type="submit" name="OrderStatus" value="Failed Delivery" data-order-id="{{ $user->order_id }}" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Failed Delivery</button> @endif </div> </form>
JS/AJAX代码
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script> $('.to-pay-button').click(function(event) { var orderId = $(this).data('order-id'); console.log("orderId: " + orderId); $.ajax({ type: 'POST', url: '{{ route('seller_order_all') }}', data: { _token: '{{ csrf_token() }}', order_id: orderId, }, success: function(response) { console.log(response); }, error: function(error) { console.error(error); } }); }); </script>
控制器代码
if($request->isMethod('post')){ $getOrder = $request->input('OrderStatus'); $orderId = $request->input('order_id'); dd($getOrder, $orderId); }
问题原因
核心问题是按钮的默认表单提交行为未被阻止:点击按钮时,浏览器会同时触发AJAX请求和表单的同步提交,而表单同步提交会优先完成,导致控制器接收到的是表单默认提交的数据(不包含order_id),而非AJAX请求的数据,因此order_id为null;而OrderStatus是按钮的value属性,会被表单提交自动携带,所以能正常获取。
解决方案
方案1:阻止表单默认提交,保留AJAX请求
修改JS代码,在点击事件开头添加event.preventDefault(),阻止表单的默认提交行为,确保AJAX请求能正常发送:
$('.to-pay-button').click(function(event) { // 阻止表单默认提交 event.preventDefault(); var orderId = $(this).data('order-id'); console.log("orderId: " + orderId); $.ajax({ type: 'POST', url: '{{ route('seller_order_all') }}', data: { _token: '{{ csrf_token() }}', order_id: orderId, OrderStatus: $(this).val() // 手动携带OrderStatus参数 }, success: function(response) { console.log(response); // 可在此添加页面状态更新逻辑 }, error: function(error) { console.error(error); } }); });
方案2:移除AJAX,用隐藏域传递参数
如果不需要异步提交,可直接在表单内添加隐藏域传递order_id,表单提交时会自动携带该参数:
<form action="{{ route('seller_order_all') }}" id="getID" method="post"> @csrf <!-- 添加隐藏域传递order_id --> <input type="hidden" name="order_id" value="{{ $user->order_id }}"> <div class="col d-flex flex-column toggle-action" id="{{ $user->order_id }}-{{ $user->product_name }}-{{ $user->status }}" style="position: relative; border: 0.5px solid #8D8D8D; padding-left: 5px; margin-top: 8px; margin-left: -92px; width: 124.075px; background: #ffffff;"> @if ($user->status == 'To Pay') <button class="btn to-pay-button" name="OrderStatus" value="To Pay" type="submit" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">To Ship</button> @endif @if ($user->status == 'To Ship') <button class="btn to-pay-button" name="OrderStatus" value="To Ship" type="submit" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Shipping</button> @endif @if ($user->status == 'Shipping') <button class="btn to-pay-button" type="submit" name="OrderStatus" value="Completed" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Completed</button> <button class="btn to-pay-button" type="submit" name="OrderStatus" value="Failed Delivery" style="padding: 0px; text-align: left; padding-bottom: 0px; font-size: 15px;">Failed Delivery</button> @endif </div> </form>
此方案下可完全移除AJAX代码,控制器无需修改即可同时获取OrderStatus和order_id。
内容的提问来源于stack exchange,提问作者Sequoia
相关产品推荐
相关产品推荐

