Laravel 表单验证失败跳首页的解决办法

发布于 2023-03-31 14:34:30阅读 829

首先,官方不觉得这是一个问题

如果在传统 HTTP 请求期间验证失败,则会生成对先前 URL 的重定向响应。如果传入的请求是 XHR,将将返回包含验证错误信息的 JSON 响应。

https://learnku.com/docs/laravel/9.x/validation/12219#quick-writing-the-validation-logic

问题复现

cuiwei@weideMacBook-Pro ~ % curl -X POST 'http://laravel.cw.net/api/login' \
--header 'Content-Type: application/json' \
--data '{
    "email1": "11@qq.com",
    "password": "a"
}'

...
        Redirecting to <a href="http://laravel.cw.net">http://laravel.cw.net</a>.
    </body>
</html>

如上,一个正常的请求,因为参数错误,跳首页去了。。

按照官方的说法,模拟 XHR 请求,即增加 header 头X-Requested-With: XMLHttpRequest

cuiwei@weideMacBook-Pro ~ % curl -X POST 'http://laravel.cw.net/api/login' \
--header 'Content-Type: application/json' \
--header 'X-Requested-With: XMLHttpRequest' \
--data '{
    "email1": "11@qq.com",
    "password": "a"
}'
{"message":"The email field is required.","errors":{"email":["The email field is required."]}}

这下符合预期了。如果这个项目只是前端对接,默认就是ajax请求,很合理。

但我这个项目有 Android端 和 iOS端,让他们额外加这么一个参数就不合适了。

解决方案

方案1

重写 failedValidation 方法

<?php
    
namespace App\Http\Requests;
 
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
 
class BaseRequests extends FormRequest
{
    /**
     * validate验证失败模板
     * @param Validator $validator
     */
    protected function failedValidation(Validator $validator)
    {
        $message = '';
        foreach (json_decode(json_encode($validator->errors()),1) as $error){
            $message = $error[0];
            break;
        }
        throw (new HttpResponseException(response()->json([
            'code' => 400,
            'msg'  => $message,
            'data' => []
        ])));
    }
}

https://blog.csdn.net/woshissss/article/details/120397036

方案2

方案1我没试,借鉴网上的。重点是方案2

拦截ValidationException异常

<?php
namespace App\Exceptions;

class Handler extends ExceptionHandler
{
    public function render($request, Throwable $e)
    {
        if ($e instanceof ValidationException) {
            //errorValidate为自定义的统一输出,重点是你拿到了$e
            return $this->errorValidate($e->errors(), $e->getCode(), $e->getMessage());
        }
        //其他异常
        if ($e instanceof NotFoundHttpException) {
            return $this->errorNotFound();
        }
        return $this->error(new \ArrayObject(), $e->getCode() ?: 400, $e->getMessage());
    }
}

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验