Laravel 验证器抛出异常而不是重定向回来

Posted

技术标签:

【中文标题】Laravel 验证器抛出异常而不是重定向回来【英文标题】:Laravel validator throws an exception instead of redirecting back 【发布时间】:2016-04-09 05:28:37 【问题描述】:

升级到 Laravel 5.2 后,我遇到了 laravel 验证器的问题。当我想验证控制器中的数据时,以这段代码为例。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class ContactController extends Controller

    public function storeContactRequest(Request $request)
    
        $this->validate($request, [
            '_token' => 'required',
            'firstname' => 'required|string'
            'lastname' => 'required|string'
            'age' => 'required|integer',
            'message' => 'required|string'
        ]);

        // Here to store the message.
    

但不知何故,当我输入无效数据时,它不会将我重定向回上一页并将一些消息闪现到会话,但它会触发异常并返回 500 错误页面。

这是我得到的例外。 我在文档中读到 ValidationException 是新的而不是 HttpResponseException 但我不知道它是否与此有关。

[2016-01-05 11:49:49] production.ERROR: exception 'Illuminate\Foundation\Validation\ValidationException' with message 'The given data failed to pass validation.' in /home/vagrant/Code/twentyre-webshop/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php:70

当我使用单独的请求类时,它只会重定向回错误消息。在我看来,只有控制器中使用的 validate 方法会受到这种行为的影响。

【问题讨论】:

这是设计使然。请求类执行重定向,如果您使用 ValidatesRequests trait 和 validate() 方法手动验证,则需要捕获异常并自己处理。 但是当我在控制器中这样使用它时如何捕获异常? 将其包装在 try/catch 子句中 谢谢我修好了我不知道它没有自动重定向是故意的。 @DB93 你是怎么解决的?你在哪里重定向? 【参考方案1】:

可能会节省一些时间,另一个问题是您在视图中调用validator-&gt;validate(),而不是在控制器中

我在视图中调用,因为我有一个在视图上触发的延迟加载组件

【讨论】:

【参考方案2】:

对于 laravel 5.2,我必须添加这一行:

    if ($e instanceof ValidationException) 
    
         return redirect()->back()->withInput();
    

在 App\Exceptions\Handler.php 中,以及以下标头:

    use Illuminate\Session\TokenMismatchException;
    use Illuminate\Database\Eloquent\ModelNotFoundException;
    use Symfony\Component\HttpKernel\Exception\HttpException;
    use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
    use Illuminate\Validation\ValidationException;
    use Illuminate\Auth\AuthenticationException;

【讨论】:

【参考方案3】:

出于我的目的,我在 Laravel 5.3 中构建了一个完全基于 API 的应用程序,该应用程序是从 Laravel 5.1 手动升级的。我只需要 Laravel 回复需要修复我的 FormRequest 的验证错误。

添加这一行:

elseif ($e instanceof ValidationException) 
 
        return $this->convertValidationExceptionToResponse($e, $request);
 

在这之后:

    if ($e instanceof ModelNotFoundException) 
        $e = new NotFoundHttpException($e->getMessage(), $e);
    

App\Exceptions\Handler.php 中为我做了诀窍,并在使用 FormRequest 验证时返回了预期的验证错误。

请在此处查看我的 cmets:@ratatatKE's comments on github

【讨论】:

【参考方案4】:

来自laravel 文档的示例。您可以使用 Validator 外观,自定义验证失败的行为

public function store(Request $request)

    $validator = Validator::make($request->all(), [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    if ($validator->fails()) 
        return redirect('post/create')
                    ->withErrors($validator)
                    ->withInput();
    

    // Store the blog post...

【讨论】:

【参考方案5】:

这就是我在 Laravel 5.3 中的处理方式(通过修改 Handler.php

https://***.com/a/42852358/3107185

【讨论】:

【参考方案6】:

我在将 4.2 升级到 5.3 时遇到了同样的问题。

这个答案对我有用。

覆盖app/Exceptions/Handler.php中的方法

protected function convertExceptionToResponse(Exception $e)

    if (config('app.debug')) 
        $whoops = new \Whoops\Run;
        $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);

        return response()->make(
            $whoops->handleException($e),
            method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500,
            method_exists($e, 'getHeaders') ? $e->getHeaders() : []
        );
    

    return parent::convertExceptionToResponse($e);

在这里找到答案:https://laracasts.com/discuss/channels/laravel/whoops-20-laravel-52

【讨论】:

这与问题无关。 我遇到了与问题相同的问题。 “Laravel 验证器抛出异常而不是重定向回来”。这就是我遇到的问题。我用上面的解决方案修复了它。导致此错误的原因可能不止一个,因此答案不止一个。我发帖是为了帮助像我一样遇到此错误的人。【参考方案7】:

更新您的 App\Exceptions\Handler 课程

use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Validation\ValidationException;

/**
 * A list of the exception types that should not be reported.
 *
 * @var array
 */
protected $dontReport = [
    AuthorizationException::class,
    HttpException::class,
    ModelNotFoundException::class,
    ValidationException::class,
];

我还建议您阅读文档如何迁移到 laravel 5.2,因为有一些重大更改。例如,ValidatesRequests trait 抛出 Illuminate\Foundation\Validation\ValidationException 而不是 Illuminate\Http\Exception\HttpResponseException

Documentation how to migrate from Laravel 5.1 to 5.2

【讨论】:

这不会为 OP 提供他们需要的结果 - 它不会重定向到上一页并闪现验证错误。 我确实将 ValidationException 添加到 dontReport 属性,但它没有解决我的问题。我已阅读迁移文档并将所有更改应用于我的项目,但这是唯一对我来说失败的事情。

以上是关于Laravel 验证器抛出异常而不是重定向回来的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:正确保存后返回重定向抛出 SQLSTATE [23000]:完整性约束违规

Laravel如何在自动重定向验证后发送参数以查看

AngularJs - 服务器抛出异常''XMLHttpRequest 无法加载预检的“URL”响应无效(重定向)'

如何使用 Laravel 5.3 注销并重定向到登录页面?

Laravel 5.4 POST 到 API 重定向 302 而不是返回验证错误

Laravel 5.1 - 抛出异常和 abort() 的区别