Laravel异步ajax表单请求数据验证422失败的解决方法

作者: 温新

分类: 【Laravel】

阅读: 3568

时间: 2020-12-13 16:38:58

需求

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

请登录后再评论