【问题标题】:Laravel validation error not returning as json responseLaravel 验证错误未作为 json 响应返回
【发布时间】:2022-10-18 04:11:56
【问题描述】:

当尝试使用 javascript 捕获我的 Laravel 验证错误时,它一直以 html 格式而不是 json 格式为我提供数据,我的验证看起来很正常。注意我使用的是 vue.js 3,如果验证通过了控制器中的实际方法工作正常,这只是一个验证问题。

$request->validate([
       'first_name' => ['required', 'string', 'min:3', 'max:255'],
       'last_name' => ['required', 'string', 'min:3', 'max:255'],
       'email' => ['required', 'email', 'min:3', 'max:255'],
       'message' => ['required', 'string', 'min:3']
   ]);

我的获取方法如下:

fetch('/contact-us', {
            method: 'POST',
            headers: {
                'CONTENT-TYPE': 'application/json'
            },
            body: JSON.stringify(this.form)
        }).then((response) => response.text())
            .then((data) => {
                console.log(data);
                //data = JSON.parse(data);
            }).catch(function(error) {
            console.log('Error: ' + error);
        });

我的网络路线是:

Route::post('/contact-us', [IndexController::class, 'contactForm']);

html格式的错误是:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link href="/css/app.css" rel="stylesheet" />
<script src="/js/app.js" defer></script>
</head>
<body>
<style>
body{
    margin: 0 !important;
    overflow-x: hidden;
}
.container {
    padding-top: 20px;
}
</style>
<div id="app" data-page="{&quot;component&quot;:&quot;ContactUs&quot;,&quot;props&quot;:{&quot;errors&quot;:{&quot;email&quot;:&quot;The email must be a valid email address.&quot;},&quot;csrf&quot;:&quot;tFYwkcZZhNfeb2WXDwdnSv4dchujDvSvLfFGhHW1&quot;},&quot;url&quot;:&quot;\/contact-us&quot;,&quot;version&quot;:&quot;0f4e2ee0f7e2ca9da665d2f8035743df&quot;}"></div></body>

【问题讨论】:

  • 这可能是一个令牌问题。您是否使用 Sanctum 来验证您的前端应用程序?
  • 它不是 api,该站点也没有登录系统。我已经让它使用手动验证类并手动返回 json 响应来工作,但这不是一个好方法,因为它使控制器看起来很乱。

标签: javascript laravel


【解决方案1】:

如果在传统 HTTP 请求期间验证失败,则会生成对前一个 URL 的重定向响应。

如果传入请求是 XHR 请求,将返回包含验证错误消息的 JSON 响应。

首先我认为/contact-us是 Web 路由而不是 API 路由。

$request-&gt;validate() 失败时的默认行为是将您重定向到带有 MessageBag 的先前 Web 路由。

为了防止这种默认行为,您需要将验证过程包装在试着抓阻止并捕获IlluminateValidationValidationException 异常并从[IndexController::class, 'contactForm'] 返回错误消息。

错误消息数组将自动转换为 JSON 响应。

try {
    $request->validate([
        'first_name' => ['required', 'string', 'min:3', 'max:255'],
        'last_name' => ['required', 'string', 'min:3', 'max:255'],
        'email' => ['required', 'email', 'min:3', 'max:255'],
        'message' => ['required', 'string', 'min:3']
    ]);
} catch (IlluminateValidationValidationException $th) {
    return $th->validator->errors();
}

示例响应:

{
    "first_name": [
        "first name field is required."
    ],
    "last_name": [
        "last name field is required."
    ],
    "email": [
        "L'E-mail field is required."
    ],
    "message": [
        "message field is required."
    ]
}

【讨论】:

  • 有没有办法将它从 XHR 交换到 fetch 或添加 fetch 到它?
  • @sgb999 当文档说 XHR 请求隐式引用您使用的 JS 获取 API 时。说“我使用 XHR”或“我使用了 fetch API”可以互换使用。我想在你的 VueJS 前端使用 API 路由而不是 Web 路由更有趣
  • 另外,您是否禁用了 VerifyCsrfToken 中间件?因为我看到您没有在 fetch() 中包含任何令牌
  • 它包含在我发送的表单对象中。
【解决方案2】:

laravel docs 天给响应一个 422 ,它在通常的错误捕获块中抛出一个错误。可以通过将此捕获错误添加到您的 json 发布请求中来提取此数据

.catch(error => {
            if (error.response.data.errors) {
                console.log(error.response.data.errors);
            }
        });

【讨论】:

    【解决方案3】:

    如果在请求中指定 Accept:application/json 头,laravel 将返回 json 响应

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-09
      • 2021-01-24
      • 2016-11-18
      • 2017-03-29
      • 1970-01-01
      • 2015-12-09
      • 2017-12-11
      • 1970-01-01
      相关资源
      最近更新 更多