自定義 Laravel Validator 所返回的響應

原文地址:https://prinzeugen.net/custom...php

不得不說 Laravel 的 Validation 是極好的,很是易於使用,麻麻不再用擔憂我要寫一大堆驗證啦 ~( ^ω^)laravel

可是這個 Validator 有一個神祕的地方 ( -д-),正如官方文檔所說,它會自動判斷當前請求是否爲 Ajax 發送的,若是是,則在驗證失敗的時候返回一個 JsonResponse 響應而不是 RedirectResponse 響應。ajax

可是,這個 JSON 響應的狀態碼,是 422。數組

WTF!坑爹呢這是!要知道 422 這個狀態碼是通不過 jQuery.ajax.success 的啊!app

在網上找了一圈,愣是沒找着什麼好一點的解決方法(全是叫你在 $.ajax.failed 裏處理錯誤的)。函數

沒辦法,本身動手豐衣足食,總之先看看文檔:自定義閃存的錯誤消息格式this

哦哦,看來咱們能夠在控制器基類中自定義錯誤的格式,因而我試着在 formatValidationErrors 方法中返回了一個狀態碼爲 200 的 Illuminate\Http\JsonResponse。可是這樣是行不通的,這個方法要求咱們要返回一個數組,因此咱們就不能使用這種小 trick 了(固然若是你願意直接在這個方法裏輸出 JSON 文本而後 exit 的話也沒事)。spa

既然這裏沒辦法了,咱們就得從 ExceptionHandler 下手了。衆所周知 Laravel 的驗證器會拋出一個 ValidationException 異常,此異常在被捕獲後會被 Laravel 的基異常處理器給渲染成 Http 響應(判斷是否爲 Ajax 請求也是在這裏作的)。.net

找到 Laravel 的基異常處理器 Illuminate\Foundation\Exceptions\Handler 後,咱們能夠發現對於 ValidationException 這類的異常,Laravel 是直接從裏面取出響應返回回去的。也就是說,具體的異常渲染是在 ValidationException 對象內完成的:調試

/**
 * Render an exception into a response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $e
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function render($request, Exception $e)
{
    if ($e instanceof HttpResponseException) {
        return $e->getResponse();
    } elseif ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    } elseif ($e instanceof AuthenticationException) {
        return $this->unauthenticated($request, $e);
    } elseif ($e instanceof AuthorizationException) {
        $e = new HttpException(403, $e->getMessage());
    } elseif ($e instanceof ValidationException && $e->getResponse()) {
        # 注意這裏
        return $e->getResponse();
    }

    if ($this->isHttpException($e)) {
        return $this->toIlluminateResponse($this->renderHttpException($e), $e);
    } else {
        return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e);
    }
}

一顆賽艇!既然看到了但願,咱們就繼續找下去。不過既然知道了 Laravel 本來的異常處理器是直接取出響應就輸出出去了,那咱們就先看看這個取出來的 Response 究竟是個啥:

class Handler extends ExceptionHandler
{
    public function render($request, Exception $e)
    {
        if ($e instanceof ValidationException) {
            dd($e->getResponse());
        }
    }
}

這裏咱們用到了 Laravel 一票幫助函數中很是好用的一個函數 —— dd(),這個函數的功能差很少就是一個漂亮的 var_dump() 加上 exit(),用來調試再方便不過了:

哦?這個方法獲得的居然是一個標準的 JsonResponse 響應!

既然是這樣,那咱們就能夠很方便的使用它的 setStatusCode 方法來設置其響應碼了。這個方法是繼承自 Symfony\Component\HttpFoundation\Response 的,有興趣的能夠去讀一讀。

綜上所述,最後咱們所須要作的就只是在 app/Exceptions/Handler.phphandle 方法中添加一個對於 ValidationException 的判斷:

if ($e instanceof ValidationException) {
    return $e->getResponse()->setStatusCode(200);
}

結果以下:

謹以此文記錄,願能幫到後來人~ (ゝ∀・)

固然你若是對於代碼的整潔沒那麼多要求的話也用不着用這種方法就是了

相關文章
相關標籤/搜索