【问题标题】:Unable to process form fields in ajax with Laravel无法使用 Laravel 处理 ajax 中的表单字段
【发布时间】:2020-08-22 20:08:06
【问题描述】:

我正在使用 Laravel 7 和 PHP 7.4。我正在使用 ajax 调用提交表单并获得 Json 响应以显示相关错误(如果有)。

serialize() ajax 调用中的表单。我的问题是,针对我应用验证的每个字段,我都会收到 422 Unprocessable Entity

令人惊讶的是,如果我的字段不为空,我仍然会收到 required 错误,这很奇怪。

我发现过去遇到过这个问题的人要么已经改用另一种方法,要么通过点击和试用方法找到了解决方案。我的验证是根据 Laravel 文档进行的。

为什么我会收到此错误,正确的解决方案是什么?

刀片视图

<form method="POST" name="register_name" id="register_forms" action="{{ route('verifydata') }}">
    @csrf
    <input placeholder="Name" id="register_name" type="text" />
    <input id="my-register" type="submit" value="Continue">
</form>

Javascript

$("#my-register").click(function(e) {
    e.preventDefault();

    var _token = $('input[name="_token"]').val();
    var data = $('#register_forms').serialize()
    $.ajax({
        type: "post",
        url: "{{ url('verifydata') }}",
        data: {
            _token: _token,
            data: data
        },
        dataType: 'json',
        success: function(data) {
            $('#success_message').fadeIn().html(data.message);
        },
        error: function(err) {
            if (err.status == 422) { // when status code is 422, it's a validation issue
                console.log(err.responseJSON);
                $('#success_message').fadeIn().html(err.responseJSON.message);

                console.warn(err.responseJSON.errors);
                $.each(err.responseJSON.errors, function(i, error) {
                    var el = $(document).find('[name="' + i + '"]');
                    el.after($('<span style="color: red;">' + error[0] + '</span>'));
                });
            }
        }
    });
    /**Ajax code ends**/
});

控制器

public function verifydata(Request $request)
{
    $this->validate($request, [
        'name' => 'required', 'string', 'max:255',
    ]);

    $name = $request->register_name;

    return response()->json([
        'message' => $name
    ]);
}

【问题讨论】:

  • 'name' =&gt; 'required', 'string', 'max:255', 应该是一个数组 'name' =&gt; ['required', 'string', 'max:255'] laravel.com/docs/7.x/validation
  • @kerbh0lz 它仍然在说“422 Unprocessable Entity”。

标签: php laravel


【解决方案1】:

首先,尝试了解您遇到了什么错误,因此请阅读此内容

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422

超文本传输​​协议 (HTTP) 422 Unprocessable Entity 响应状态码表示服务器理解请求实体的内容类型,请求实体的语法正确,但无法处理包含的指令。

我看到三个错误:

首先:您在请求中告诉您正在发送 JSON 数据,这是不正确的

dataType: 'json',

因为 .serialize() 不是生成 JSON,而是序列化的 POST 正文

它看起来像:name=kamil&surname=kamil

因此,删除 dataType: 'json' 并将其添加到 data

data : $('#register_forms').serialize() + "&_token=" + _token

如果要发送 JSON 数据,则需要创建 JSON 数据。

Sedcond:您的“输入”中没有“名称”属性。

<form method="POST" name="register_name" id="register_forms" action="{{ route('verifydata') }}">
    <input placeholder="Name" name="register_name" id="register_name" type="text" />
    <input id="my-register" type="submit" value="Continue">
</form>

三:在你的PHP代码中,需要指定这样的验证规则

https://laravel.com/docs/7.x/validation

所以,这个:

$this->validate($request, [
    'name' => ['required', 'string', 'max:255'],
]);

或者,这个

$this->validate($request, [
    'name' => 'required|string|max:255',
]);

修复此问题后,它应该可以工作了。

【讨论】:

  • 仅供参考,根据$.ajax docs dataType 是为了响应而不是请求。 :)
  • 是的,如果我想得到 json 响应,我必须定义 dataType:json。
  • 我刚刚添加了这一行 " data : $('#register_forms').serialize() + "&_token=" + _token," 我的 50% 问题得到了解决,那就是如果我的字段有价值然后 ajax 返回 200 ok 状态。 ........现在的问题是,当我将字段留空时,它会返回错误“422 Unprocessable Entity”,这意味着我的验证不起作用!
【解决方案2】:

您提供的代码存在一些问题。

您没有为您的&lt;input /&gt; 提供name 属性。将您的 &lt;input /&gt; 更改为:

<input name="name" placeholder="Name" id="register_name" type="text"/>

将序列化的数据直接分配给data属性,而不是在对象内部:

$.ajax({
    type: 'POST',
    url: "{{ url('verifydata') }}",
    data: data,
    dataType: 'json',
    ...
});

您当前拥有的代码(假设输入字段有名称)将在服务器上产生以下结果:

[
    '_token' => 'cqmRx74gJiSXyAFXBdq5UagX68O6OvYqX67WwIAZ',
    'data'   => '_token=cqmRx74gJiSXyAFXBdq5UagX68O6OvYqX67WwIAZ&name=foobar' 
]

如果是body的子属性,序列化的数据不会被解析。

此外,您不需要添加 _token 属性,因为您使用了 @csrf,它应该已经包含在您的表单中。


最后,将验证规则包装在一个数组中:

$this->validate($request, [
    'name' => ['required', 'string', 'max:255'],
]);

或由管道分隔的单个字符串 (|):

$this->validate($request, [
    'name' => 'required|string|max:255'],
]);

【讨论】:

  • 我采取了您推荐的所有步骤。我刚刚从我的 ajax 调用中删除了令牌,它开始给出错误“状态代码:419 未知状态”。添加令牌后,我的问题又回来了,所以我认为令牌在这里是强制性的。
  • @Shaan 您是否从表单中删除了@csrf 指令?如果是这样,您需要将其放回原处。
  • 不,我只是按照您的说明从我的 ajax 调用中删除了 _token。 @csrf 在我的代码中,我得到了我所说的错误。
  • @Shaan 哦,这很奇怪。我刚刚在本地对其进行了测试,它应该可以正常工作,因为@csrf 会将_token 字段添加到您的表单中,serialize() 也应该包含该数据。我建议检查浏览器中的网络选项卡以确保它不被包含在内。如果是,您可能需要进行硬刷新。
  • @Shaan ...或者,您可以将令牌作为标头包含在内:laravel.com/docs/7.x/csrf#csrf-x-csrf-toke
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2017-12-24
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多