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></select>内为每个<option></option>添加动态selected属性:
<select name="status"><br> <option value="draft" old :>草稿</option> <br> <option value="published" old :>已发布</option> <br></select>
注意:<select value="{{ old('status') }}"></select>完全无效,浏览器根本不认这个写法。
方法二:用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,不再触发重定向。











