Laravel验证失败后输入数据丢失是因为未调用withInput()或session失效;下拉框需手动用old()判断selected;重定向不传递模型变量,需在failedValidation()中with()透传;API验证应重写failedValidation()返回JSON而非跳转。

当Laravel表单验证失败后重定向回原页面,输入框里的文字、下拉选项的选中状态、多行文本框内容默认会全部清空——这不是浏览器行为,而是你没让Laravel把原始数据存进session。
为什么old()取不到值
第一步:确认控制器是否调用了withInput()。使用Validator::make()手动验证时,【Laravel不会自动保存输入数据】,必须显式链式调用->withInput(),否则old('email')永远返回null。
第二步:检查FormRequest类是否被正确继承并启用。若自定义了UpdatePostRequest但控制器里写的是$request->validate()而非$this->validate($request, ...)或直接注入UpdatePostRequest,验证流程就绕过了FormRequest的自动withInput()机制。
第三步:打开浏览器开发者工具→Application→Cookies,查看laravel_session是否存在且未过期。如果session丢失,哪怕代码全对,old()也读不到任何东西。
下拉框选中状态怎么恢复
方法一:在<select>内为每个<option>添加动态selected属性:
<select name="status"><br> <option value="draft" {{ old('status') == 'draft' ? 'selected' : '' }}>草稿</option><br> <option value="published" {{ old('status') == 'published' ? 'selected' : '' }}>已发布</option><br></select>
注意:<select value="{{ old('status') }}">完全无效,浏览器根本不认这个写法。
方法二:用old()配合old('status') ?? $post->status做兜底,避免首次访问时old()为空导致默认无选中项。
重定向目标页模型变量丢失
FormRequest验证失败后redirect()->back()只保留请求数据和错误消息,【不会自动重传控制器中传给视图的模型变量(如$product)】。例如你在edit.blade.php里写了{{ $product->name }},验证失败跳回来时就会报Trying to get property 'name' of non-object。
解决方式是重写FormRequest中的failedValidation()方法:
在app/Http/Requests/UpdateProductRequest.php里添加:
protected function failedValidation(Validator $validator)<br>{<br> return redirect()<br> ->back()<br> ->withErrors($validator)<br> ->withInput()<br> ->with('product', $this->route('product'));// ← 关键:手动透传模型<br>}
然后在Blade模板中改用{{ session('product')->name ?? old('name') }}安全读取。
API接口验证失败为何跳首页
API路由默认走Web中间件组,而FormRequest的failedValidation()方法抛出ValidationException后,会被Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull等中间件捕获并转成302跳转——这在API场景下完全错误。
必须新建一个基类ApiRequest,继承FormRequest并重写failedValidation():
protected function failedValidation(Validator $validator)<br>{<br> throw new HttpResponseException(<br> response()->json([<br> 'message' => 'Validation failed',<br> 'errors' => $validator->errors(),<br> ], 422)<br> );<br>}
所有API表单验证请求都继承这个ApiRequest,不再触发重定向。


















