即使令牌匹配,Laravel ajax 422 也无法处理实体

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33137946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:28:51  来源:igfitidea点击:

Laravel ajax 422 Unprocessable Entity even when token is matching

ajaxformslaravel-5

提问by Jakub Kohout

I'm getting 422 Unprocessable Entity error even when I'm submitting my form via Ajax.

即使我通过 Ajax 提交表单,我也会收到 422 Unprocessable Entity 错误。

My javascript file

我的 javascript 文件

$.ajaxSetup({
    headers: {
        'X-XSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

$('.keywords-plan-form').submit(function(event) {
    event.preventDefault();

    $.ajax({
        url: '/laravel/public/keywordsplans',
        type: 'POST',
        data: $(this).serialize(),
        success: function(data){
            alert(data);
            // success logic
        },
        error: function(data){
            // Error...
            var errors = $.parseJSON(data.responseText);

            console.log(errors);

            $.each(errors, function(index, value) {

            });

        }
    });

});

as you can see I added X-XSRF-TOKEN****strong textto ajax header.

如您所见,我在 ajax 标题中添加了X-XSRF-TOKEN****strong 文本

This is my '' tag

这是我的''标签

<meta name="csrf-token" content="{{ csrf_token() }}">

my Form Datain chrome debuger

我在 Chrome 调试器中的表单数据

_token:5j6DGhhTytbIRB1GrW9Wml9XrOxmKjgE9RiGa4Gf
date:
keyword[0]:Lorem ipsum
keyword[1]:Is dolor amet
keyword[2]:plumber tampa

Request Headers

请求头

X-XSRF-TOKEN:5j6DGhhTytbIRB1GrW9Wml9XrOxmKjgE9RiGa4Gf
.....

am I doing something wrong or forgetting something?

我做错了什么还是忘记了什么?

回答by andrei.culda

I don't think that csrf token is the issue here. If it were you would get TokenMissmatchException and not Unprocessable Entity. Do you happen to have a request validator in your Controller like this?

我不认为 csrf 令牌是这里的问题。如果是这样,您将获得 TokenMissmatchException 而不是 Unprocessable Entity。你碰巧在你的控制器中有一个这样的请求验证器吗?

    $validator = Validator::make($request->all(), [

            'username' => 'required|max:30|min:6|unique:users',

            'email' => 'required|email|max:50|unique:users',

            'password' => 'required|confirmed|min:6',

        ]);

If so maybe you can do something like this:

如果是这样,也许你可以做这样的事情:

    if ($validator->fails()) {

            if($request->ajax())
            {
                return response()->json(array(
                    'success' => false,
                    'message' => 'There are incorect values in the form!',
                    'errors' => $validator->getMessageBag()->toArray()
                ), 422);
            }

            $this->throwValidationException(

                $request, $validator

            );

        }

After that you can catch validation errors in your ajax error handler like this:

之后,您可以在 ajax 错误处理程序中捕获验证错误,如下所示:

  $('.keywords-plan-form').submit(function(event) {
       event.preventDefault();

$.ajax({
    url: '/laravel/public/keywordsplans',
    type: 'POST',
    data: $(this).serialize(),
    success: function(data){
        alert(data);
        // success logic
    },
    error: function(jqXhr, json, errorThrown){// this are default for ajax errors 
        var errors = jqXhr.responseJSON;
        var errorsHtml = '';
        $.each(errors['errors'], function (index, value) {
            errorsHtml += '<ul class="list-group"><li class="list-group-item alert alert-danger">' + value + '</li></ul>';
        });
        //I use SweetAlert2 for this
        swal({
            title: "Error " + jqXhr.status + ': ' + errorThrown,// this will output "Error 422: Unprocessable Entity"
            html: errorsHtml,
            width: 'auto',
            confirmButtonText: 'Try again',
            cancelButtonText: 'Cancel',
            confirmButtonClass: 'btn',
            cancelButtonClass: 'cancel-class',
            showCancelButton: true,
            closeOnConfirm: true,
            closeOnCancel: true,
            type: 'error'
        }, function(isConfirm) {
            if (isConfirm) {
                 $('#openModal').click();//this is when the form is in a modal
            }
        });

    }
});
});

And see the messages in the modal message

并查看模态消息中的 消息

回答by Vivek Chaudhary

I have solved this issue :

我已经解决了这个问题:

public function register(\Illuminate\Http\Request $request) {        
    if ($this->validator($request->all())->fails()) {
        $errors = $this->validator($request->all())->errors()->getMessages();            
        $clientErrors = array();
        foreach ($errors as $key => $value) {
            $clientErrors[$key] = $value[0];
        }
        $response = array(
            'status' => 'error',
            'response_code' => 201,
            'errors' => $clientErrors
        );            
    } else {
        $this->validator($request->all())->validate();
        $user = $this->create($request->all());
        $response = array(
            'status' => 'success',
            'response_code' => 200
        );
    }
    echo json_encode($response);
}

回答by Evgeniy Belov

Maybe someone will come in handy.

也许有人会派上用场。

422 Unprocessable Entity

422 无法处理的实体

is default error by validator laravel

是验证器 laravel 的默认错误

vendor/laravel/framework/src/Illuminate/Validation/Validator.php

If fails validate params, then throught Exception ValidationException

如果验证参数失败,则通过 Exception ValidationException

vendor/laravel/framework/src/Illuminate/Validation/ValidationException.php

where default status = 422

其中默认状态 = 422

And therethore all your ajax responses with non validate forms will be with status = 422

并且所有带有非验证表单的 ajax 响应都将是 status = 422