【问题标题】:How to debug 422 (Unprocessable Entity) Error Response in Vue/Laravel?如何在 Vue/Laravel 中调试 422(无法处理的实体)错误响应?
【发布时间】:2021-11-23 04:25:26
【问题描述】:

我正在尝试使用Vue 3 和Laravel 8 构建一个简单的contact form,但我正在努力将frontend 与backend 连接起来。现在我的代码会产生一个422 (Unprocessable Entity) 响应,但我不知道为什么以及如何调查。响应与传递的data values 无关。例如name = null 和name = myname 产生相同的错误。

contact.vue:

<template>
  <section class="contact">
    <form @submit.prevent="storeContact" method="post">
      <input type="text" placeholder="Name" v-model="user.name">
      <input type="text" placeholder="Email" v-model="user.email">
      <input type="text" placeholder="Message" v-model="user.message">
      <button action="post" type="submit">Submit</button>
    </form>
  </section>
</template>


<script>
import {ref} from "vue";

export default {
  setup() {
    let success = false;
    let error = false;
    let user = ref({
      name: null,
      email: null,
      message: null
    });
    function storeContact() {
      axios.post('/contact', Object.values(user.value)
      )
        .then((res) => {
          success = true;
        })
        .catch((error) => {
          error = true;
        })
    };
    return {
      success,
      error,
      user,
      storeContact
    }
  }
}
</script>

web.php:

<?php

use Illuminate\Support\Facades\Route;


Route::get('/', function () {
    return view('welcome');
});

Route::post('/contact', 'App\Http\Controllers\ContactController@submit');

ContactController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
  public function submit(Request $request) {
    $this->validate($request, [
      'name' => 'required',
      'email' => 'required | email',
      'message' => 'required'
    ]);
    return response()->json(null, 200);
  }
}

Browser console error:

app.js:17263 POST http://localhost:3000/contact 422 (Unprocessable Entity)

Laravel 日志没有条目。这是否意味着它是frontend problem?

编辑:

dev tools network tab 中的response 显示:

{"message":"The given data was invalid.","errors":{"name":["The name field is required."],"email":["The email field is required."],"message":["The message field is required."]}}

将这些参数更改为text/values 不会带来任何变化。

编辑2:

这些问题已排除:

Missing CSRF-Token:不,network 选项卡中存在 csrf 令牌 (XSRF)。

null passed:不,不管我通过什么,结果都是一样的。

【问题讨论】:

  • 也许:返回 response()->json(null, 200); -> 返回响应()->json(array(), 200);?
  • @OfirBaruch 没有区别
  • 验证失败时返回422。您检查过网络分接头中的请求响应吗?
  • 您能确认姓名、电子邮件和消息不为空吗?
  • @OfirBaruch 是的,当我对这些参数使用values 或text 时,它返回相同的error。

标签: php laravel vue.js httpresponse vuejs3


【解决方案1】:

正如@Mohammed Naguib 提到的,当验证失败时返回 422。 根据您的验证码 - 所有属性都是必需的。

$this->validate($request, [
  'name' => 'required',
  'email' => 'required | email',
  'message' => 'required'
]);

所以我建议将调试过程分成2个。

(1) - 前端是否发送数据?

在contact.vue 上,在发送发布请求之前。 对用户对象使用 console.debug 并检查您发送的数据。

   let user = ref({
      name: null,
      email: null,
      message: null
    });
    function storeContact() {
      console.debug(user);
      console.debug(Object.values(user.value));

      axios.post('/contact', Object.values(user.value)

检查开发人员工具上的控制台,并检查用户对象和您在请求中发送的值的 console.debug 命令的输出。

如果其中一个属性为 null - 前端有问题。

(2) - 后端

删除 $this->validate() 函数并简单地 var_dump $request 对象。您是否看到相关属性(姓名、电子邮件、地址)以及它们是否具有所需的值?

我的猜测:

如果我没记错的话Object.values(user.value) 创建一个数组 使用这些值,因此属性名称会从 请求。

【讨论】:

  • 如果可能,请分享调试结果。
  • console.debug 不会在控制台中产生任何输出。 console.log 显示值,但正如我所说,它们是否为 null 并不重要。输出保持不变 (422)
  • 我的回答的第 2 部分怎么样,与后端有关 + 我对问题的猜测
  • 对不起,我如何将接收到的值放入变量中?
  • 试试:axios.post('/contact', user
【解决方案2】:

原来我在axios.post 中有错字:

改变axios.post('/contact', Object.values(user.value)) 给axios.post('/contact', user.value)

并将数据设置为不是null 解决了我的问题。

感谢大家的帮助。

【讨论】:

    【解决方案3】:

    您遇到此问题是因为您在没有 CSRF 令牌的情况下向服务器发布。这是一个关于如何解决此问题的类似案例。

    How to pass laravel CSRF token value to vue

    您需要将 CSRF 令牌从 DOM 复制到您的 axios 请求的标头中,或者将其附加到公共标头中。完成后,您的 POST 请求将可以处理。或者,要确认这一点,您可以转到文件 app/Http/Middleware/VerifyCsrfToken.php 并将您的路径添加到 'except' 数组

    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
    
    class VerifyCsrfToken extends Middleware
    {
        /**
         * The URIs that should be excluded from CSRF verification.
         *
         * @var array
         */
        protected $except = [
            '/contact'
        ];
    }
    

    【讨论】:

    • 我在开发服务器上有welcome.blade.php. Does this not provide a csrf token? In addition I am working on the php artisan dev server. Is it necessary to provide csrf tokens`中的&lt;meta name="csrf-token" content="{{ csrf_token() }}"&gt;?
    • 要确认,您可以检查您的网络并查看 CSRF 令牌是否在正文或标头中传递(我希望在这里)但是如果您没有看到它,请尝试手动包含它以上文章中的参考资料。至于开发服务器,我不确定,但希望它不会将您与生产环境混淆
    • 您是指network/Headers 中的X-XSRF-TOKEN: eyJ..... 吗?我在Headers 中找不到CSRF token,也没有body 标签。
    • 啊,我看到你也没有在你的对象值引用中传递任何东西。 let user = ref({ name: null, email: null, message: null }); 中的 null 值实际上必须设置为实际值。我的回答不适合您的问题。我建议绑定实际值。暂时删除 ref,然后删除 Object.values() 函数并仅将用户对象作为 user.value 传递给未定义快乐编码
    • 即使我删除所有变量(来自script 和ContactController.php)和ref 并且只通过name = whatever 也会给出相同的错误。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2021-05-27
    • 2014-12-24
    • 2019-03-14
    • 1970-01-01
    • 2016-04-30
    • 2018-03-01
    相关资源
    最近更新 更多