【问题标题】:Laravel Ajax validationLaravel Ajax 验证
【发布时间】:2015-05-05 16:25:40
【问题描述】:

我了解如何通过在控制器方法中输入类名来验证请求。但是对于 Ajax 请求,According to the documentation,我应该在控制器中验证数据,因为使用验证器类将重定向而不是发送响应。

我正在看的主要部分是:

如果传入请求是 AJAX 请求,则不会重定向 生成。相反,带有 422 状态代码的 HTTP 响应将是 返回到浏览器,其中包含验证错误的 JSON 表示形式。

但是,我的控制器如下:

public function update(App\Permission $permission, Request $request)
{
    $this->validate($request, [
        'permission_description' => 'required|string'
    ]);

    ...
}

而且我这辈子都无法让它用 JSON 响应。该文档指出,如果失败,则会引发Illuminate\Contracts\Validation\ValidationException 异常,但我无法捕捉到它。

每当它失败时,它总是重定向回编辑页面。显然我不想要这个,我想要json响应。

我刚刚尝试用整个$v = Validator::make($request->all(), ...);“手动写出来”,它确实有效,但是如果它不起作用,那么使用$this->validate() 方式有什么意义呢?

$this->validate() 方法是否不适用于 AJAX,我每次都必须写很长的路?难道我做错了什么?!

以下是我尝试过的:

public function update(App\Permission $permission, UpdatePermissionRequest $request)
{
   /** Redirects rather than returns JSON if the validation fails **/
}

----------------------------------

public function update(App\Permission $permission, Request $request)
{
    $this->validate($request, [
        'permission_description' => 'required|string'
    ]);

    /** AND I've also tried: **/

    try {
        $this->validate($request, ['permission_description' => 'required|string']);
    } catch (\Illuminate\Contracts\Validation\ValidationException $e {
        echo $e; /** Echoing for debug reasons **/
        exit;
    }

    ... 
    /** Still redirects the browser, even if it is an AJAX request **/
}

-----------------------------------------

use Validator;
...
public function update(App\Permission $permission, Request $request)
{
    $v = Validator::make($request->all(), [
        'permission_description' => 'required|string'
    ]);

    if($v->fails())
    {
        return response()->json(['reply' => false]);
    }

    /** Works **/
}

更新 文档不正确。它指出$this->validate() 方法会抛出Illuminate\Contracts\Validation\ValidationException,但它不会。它会引发Illuminate\Http\Exception\HttpResponseException 异常。

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    好的,看来有两个影响因素。

    1. 它重定向而不是响应 JSON 的原因是 X-Requested-With 字段未在 AJAX 请求上设置。这个应用程序的 AJAX 包装器被设置为处理跨域请求,这似乎去除了 X-Requested-With 字段,这使得最终请求在服务器看来不是 ajax - 因此是重定向。

    2. 它没有捕获Illuminate\Contracts\Validation\ValidationException 异常的原因是没有抛出该异常。如果您打开Illuminate\Foundation\Validation\ValidatesRequest.php,并搜索函数throwValidationException(),它实际上会抛出HttpResponseException。我试图捕捉 HttpResponseException 并成功捕捉 - 我认为文档是错误的。

    解决方案是删除 ajax 请求上的跨域属性,手动添加 X-Requested-With 标头,根据 answer in this post。这将使应用程序看到它是一个 AJAX 请求。

    如果你想手动捕捉异常,你需要捕捉HttpResponseException,而不是ValidationException

    【讨论】:

    • 有同样的问题,但我是新手,所以如果你能展示一个工作示例以便我能更好地理解,我将不胜感激。
    【解决方案2】:

    您关于文档说最好在控制器中验证 AJAX 请求的说法完全不正确。

    如果您滚动 bit further down from what you linked - 您将在 FormValidation 部分看到此内容

    如果验证失败,将生成重定向响应以发送 用户回到他们之前的位置。错误也会一闪而过 到会话,以便它们可以显示。如果请求是 一个 AJAX 请求,一个带有 422 状态码的 HTTP 响应将是 返回给用户,包括验证的 JSON 表示 错误。

    换句话说 - 你没有理由不能在一个简单的 FormRequest 和你的代码中显着地做到这一点。它会自动处理它是一个 AJAX 调用的事实并返回适当的 HTTP 响应。

    我一直在我的 L5 应用程序中这样做 - 它完美无缺。

    【讨论】:

    • 是的,不幸的是,我的 ajax 请求中的一个跨域选项省略了请求中的 X-Requested-With 选项,因此对于服务器来说,它看起来像是一个标准的非 ajax 请求。
    • @Laurence 我也有类似的问题,但我想我需要一些实用的解决方案,请您看看我的帖子:stackoverflow.com/questions/44780698/…
    • @PhilCross 如果您的工作正常,请您帮忙:stackoverflow.com/questions/44780698/…
    【解决方案3】:

    简单地告诉你想要在标题中使用 json 也应该解决这个问题。 Laravel 检查请求是否为 ajax 或 json 被请求。

    if ($this->ajax() || $this->wantsJson())
    {
        return new JsonResponse($errors, 422);
    }
    

    解决方案:

    添加标题

    接受:应用程序/json

    【讨论】:

      猜你喜欢
      • 2020-08-20
      • 1970-01-01
      • 2016-08-05
      • 2018-05-31
      • 2018-01-24
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      相关资源
      最近更新 更多