Laravel中结合jQuery将submit按钮改为button类型后$request->has()失效问题
问题根因
- 原生
type="submit"按钮触发表单提交时,浏览器会自动将当前点击按钮的name属性作为表单数据的一部分携带到后端,这也是你之前控制器用$request->has()能正常区分请求类型的核心原因。 - 当你把按钮改为
type="button",通过jQuery手动调用form.submit()触发提交时,浏览器不会关联任何按钮的状态,自然不会把按钮的name字段值带到请求里,后端的$request->has()判断自然无法命中。 - 你当前编写的jQuery逻辑存在两处影响效果的问题:
- 调用
submit()后立即执行$(".loader").hide(),由于表单同步提交会阻塞JS线程,浏览器根本来不及渲染加载图标,用户完全看不到加载状态 - 没有增加按钮禁用逻辑,即使加载态正常显示,用户依然可以多次点击触发重复提交
- 调用
解决方案
可根据你对现有代码的改动需求,选择对应实现:
方案1:最小改动适配现有控制器逻辑(无需修改后端代码)
这个方案完全保留你现有控制器的$request->has()判断逻辑,只调整前端代码即可。
Blade模板代码
保留现有按钮结构即可:
<form id='form-info' class="form-info" action="{{url('/form/sendData')}}" method="post"> @csrf <input type="text" id="info" class="info" name="name" value="test"/> <button type="button" class="btn btn-xs btn-warning" name="update" id="update">Update</button> <button type="button" class="btn btn-xs btn-danger" name="delete" id="delete">Delete</button> <button type="button" class="btn btn-xs btn-info" name="email" id="email">Email</button> </form>
调整后的jQuery代码
统一监听所有按钮的点击事件,在提交前动态注入对应按钮的name字段值,同时修正加载态的渲染逻辑:
$(document).ready(function(){ // 统一绑定所有按钮的点击事件,避免重复写三段相同逻辑 $('#form-info button[type="button"]').click(function(){ const btnName = $(this).attr('name'); // 先移除之前可能注入的同名字段,避免重复提交 $('#form-info').find('input[name="' + btnName + '"]').remove(); // 动态注入当前点击按钮对应的隐藏字段,模拟原生submit的提交行为 $('<input>').attr({ type: 'hidden', name: btnName, value: '1' }).appendTo('#form-info'); // 显示加载图标 $(".loader").show(); // 禁用所有按钮,阻止重复点击 $('#form-info button').prop('disabled', true); // 加10ms延迟,让浏览器完成加载图标的渲染,再触发表单提交 setTimeout(function(){ $('#form-info').submit(); }, 10); }); });
该方案下你后端的控制器代码完全不用修改,原有的$request->has('update')类判断可以正常生效。
方案2:规范表单传参(适合后续扩展更多操作)
这个方案通过统一的动作标识字段传递操作类型,代码可读性更强,后续要新增操作按钮也更方便。
Blade模板代码
给每个按钮加上标识动作的自定义属性,同时加一个专门存动作类型的隐藏域:
<form id='form-info' class="form-info" action="{{url('/form/sendData')}}" method="post"> @csrf <input type="text" id="info" class="info" name="name" value="test"/> <input type="hidden" name="action_type" id="action_type" value=""> <button type="button" class="btn btn-xs btn-warning" data-action="update" id="update">Update</button> <button type="button" class="btn btn-xs btn-danger" data-action="delete" id="delete">Delete</button> <button type="button" class="btn btn-xs btn-info" data-action="email" id="email">Email</button> </form>
jQuery代码
$(document).ready(function(){ $('#form-info button[type="button"]').click(function(){ // 读取当前按钮对应的动作标识 const action = $(this).data('action'); // 把标识写入隐藏域 $('#action_type').val(action); // 显示加载态、禁用按钮的逻辑和方案1一致 $(".loader").show(); $('#form-info button').prop('disabled', true); setTimeout(function(){ $('#form-info').submit(); }, 10); }); });
控制器调整
把原来的判断逻辑改为读取统一的动作字段:
$action = $request->input('action_type'); if ($action == 'update') { // 原有update逻辑 } else if($action == 'delete') { // 原有delete逻辑 } else if($action == 'email') { // 原有email逻辑 }
内容的提问来源于stack exchange,提问作者Rzj Hayabusa
相关产品推荐
相关产品推荐

