Laravel异步ajax表单请求数据验证422失败的解决方法
需求
Laravel数据验证,最传统的是在控制器中进行验证,验证失败的错误信息会存储在session中,前端模板通过session来取出错误信息。控制器中大量的验证使用代码臃肿难看,Laravel中提供了优雅的写法Form Request
,但是这将导致通过ajax请求表单数据验证报422错误。
另一个场景就是前后端分离,大量使用异步请求,传统的验证已无法适应。这些问题都可以通过异常来解决。使用异常来优雅的处理表单验证。
什么是Form Request
Laravel中每一个请求都会被封装成一个Request
对象,Form Request
对象包含了额外的验证逻辑及访问权限控制的自定义Request
类。
使用Form Request验证
步骤一:生成
php artisan make:request TestRequest
步骤二:编写验证规则
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'username' => 'required|max:50',
];
}
public function messages()
{
return [
'username.required' => '用户名必填',
];
}
}
步骤三:控制器中使用
use App\Http\Requests\TestRequest;
// 依赖注入后会自动对表单数据进行验证
public function store(TestRequest $request)
{
}
到这里验证完成了,但是问题也来了。由于是ajax异步请求,那么就会发现,表单数据已经验证,同时也报了一个422错误。解决方法就是重写父类的failedValidation
方法。
步骤四:重写父类failedValidation方法
在生成的TestRequest.php
文件中重写父类方法,重写完成后就会看到熟悉的错误返回信息了。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
# 下面这三个引入不可省略
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;
class UserRequest extends FormRequest
{
# 此处省略验证规则与信息
// 重写ajax请求验证错误响应格式(防止验证422报错)
protected function failedValidation(Validator $validator)
{
// 此处自定义表单验证错误信息
$data = [
'code' => 10000,
'msg' => $validator->errors()->first(),
];
$respone = new Response(json_encode($data));
throw (new ValidationException($validator, $respone))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
}
注意:Validator、ValidationException、Response这三个一定要引入,不然会报500错误。
2020-12-14
请登录后再评论