使用event.preventDefault后Laravel应用无法登出的原因及解决办法
Laravel表单提交JS干扰登出功能的问题解决
问题回顾
作为Laravel新手,你遇到了这么个头疼的情况:你在下拉菜单里做了两个表单用来处理审核/拒绝操作,用jQuery写了提交逻辑,但这段JS一启用,自带的登出功能就失效了。
先贴一下你的相关代码,方便理解:
表单代码
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> {!! Form::open(['action'=>['AdminController@update',$upload->id,0], 'method'=>'POST']) !!} {{Form::hidden('_method','PUT')}} <a class="dropdown-item" href="/manage">Approve</a> {!! Form::close()!!} {!! Form::open(['action'=>['AdminController@update',$upload->id,1], 'method'=>'POST']) !!} {{Form::hidden('_method','PUT')}} <a class="dropdown-item" href="/manage">Reject</a> {!! Form::close()!!} </div>
提交用的jQuery代码
$(".dropdown-item").click(function(e){ e.preventDefault(); $(this).closest("form").submit(); });
登出链接代码
<a class="dropdown-item" href="#" onclick="window.location='{{ route('logout') }}'">Log out</a>
问题根源
其实原因很简单:你的jQuery选择器$(".dropdown-item")把所有带这个类的元素都选中了,包括你的登出按钮!
当你点击登出链接时,JS会先执行e.preventDefault()——这直接阻止了链接的默认行为,包括你写在onclick里的跳转逻辑。然后代码尝试找最近的<form>元素提交,但登出链接根本不在任何表单里,所以这一步啥也做不了,最终导致登出完全没反应。
解决方案(无需修改登出代码)
这里给你两种实用的方案,都不用动你的登出链接代码,选哪个看你偏好:
方案1:给表单内的操作按钮加专属类
给审核和拒绝的<a>标签加一个额外的类(比如form-action-item),让JS只监听这些需要提交表单的按钮:
修改后的表单代码:
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> {!! Form::open(['action'=>['AdminController@update',$upload->id,0], 'method'=>'POST']) !!} {{Form::hidden('_method','PUT')}} <a class="dropdown-item form-action-item" href="/manage">Approve</a> {!! Form::close()!!} {!! Form::open(['action'=>['AdminController@update',$upload->id,1], 'method'=>'POST']) !!} {{Form::hidden('_method','PUT')}} <a class="dropdown-item form-action-item" href="/manage">Reject</a> {!! Form::close()!!} </div>
对应的jQuery代码改成:
$(".form-action-item").click(function(e){ e.preventDefault(); $(this).closest("form").submit(); });
这样只有表单里的操作按钮会触发提交逻辑,登出链接完全不受影响。
方案2:在JS中判断元素是否在表单内
不用修改任何HTML,直接在现有JS里加个判断:只有当点击的.dropdown-item确实在表单内部时,才执行阻止默认和提交操作,否则就让默认行为正常运行:
$(".dropdown-item").click(function(e){ // 查找当前元素最近的父级表单 const targetForm = $(this).closest("form"); // 如果找到表单,才执行提交逻辑 if (targetForm.length > 0) { e.preventDefault(); targetForm.submit(); } // 没找到的话,就跳过,让登出的onclick正常执行 });
这个方案更省心,不用改HTML,直接调整JS逻辑就行。
内容的提问来源于stack exchange,提问作者Robert Ross
相关产品推荐
相关产品推荐

