【问题标题】:Validation errors in AJAX modeAJAX 模式下的验证错误
【发布时间】:2013-06-10 11:19:33
【问题描述】:

目前我使用它通过 ajax 显示验证错误:

            if (data.validation_failed == 1)
            {
                var arr = data.errors;
                $.each(arr, function(index, value)
                {
                    if (value.length != 0)
                    {
                        $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
                    }
                });
                $('#ajax-loading').hide();
                $("#validation-errors").show();
            }

它工作正常,完全符合我的需要。

问题是我必须做些什么才能将错误从 laravel 传输到 ajax:

    $rules = array( 
        'name'  => 'required',
        'password' => 'required'
    );

    $v = Validator::make(Input::all(), $rules);

    if ( ! $v->passes())
    {

    $messages = $v->messages();

    foreach ($rules as $key => $value)
    {
        $verrors[$key] = $messages->first($key);
    }

        if(Request::ajax())
        {                    
            $response_values = array(
                'validation_failed' => 1,
                'errors' => $verrors);              
        return Response::json($response_values);
        }
        else
        {
        return Redirect::to('login')
            ->with('validation_failed', 1)
            ->withErrors($v);
        }       

    }

如果我想将字段名作为键,我必须迭代 $rules,但即使我不使用字段名作为键,我也必须迭代错误消息来构造 $verrors。

如何在无需迭代的情况下将 $v-&gt;messages() 转换为 $verrors 的等价物?因为Response::json() 需要一个数组而不是一个对象。

【问题讨论】:

    标签: php laravel laravel-4


    【解决方案1】:

    我想分享对我有用的东西:

    在后端,我做了与本文第一个答案指出的类似的事情:

    (在“$arrayValidate”中我使用正则表达式进行验证,如果您不知道它们是如何工作的,只需给我发短信,我会很乐意解释)

        public function createUser(Request $request){
            
        $arrayRequest = [
            "name" => $request->name,
            "document" => $request->document,
            "password" => $request->password
        ];
    
        $arrayValidate = [
            "name" => ["required",'regex:/^[a-zñÑáéíóúÁÉÍÓÚ]+$/i'],
            "document" => ["required",'regex:/^\d{6,12}$/', 'unique:tb_usuarios'],
            "password" => ["required",'regex:/^.{8,}$/']
        ];
    
        $response = Validator::make($arrayRequest, $arrayValidate);
    
        if($response->fails()){
            return Response::json([
                'response' => false,
                'errors' => $response->getMessageBag()->toArray()
            ], 422);
        }
    
        $response = User::create([
            "name" => $request->name,
            "document" => $request->document,
            "password" => Hash::make($request->password)
        ]);
    
        return Response::json(['success' => true], 200);
        }
    

    在使用Javascript的前端,我们获得准备处理的验证响应:

        axios({
            url: `create`,
            method: 'post',
            responseType: 'json',
            data: datos // Your data here
        })
        .then((res) => {
            if(res.status==200) {
                return res.data
            }
            console.log(res)
        })
        .catch((error) => {
            // Here we obtain an object of arrays with the response of the validation, which fields are correct and which ones are incorrect
            console.log(error.response.data.errors)            
        })
        .then((res) => {
            console.log(res)    
        })
    

    【讨论】:

      【解决方案2】:

      我做到了,试试这个希望它能帮助你解决相关字段后的渲染错误。

      $("#booking_form").submit(function(e){
                      e.preventDefault();
                      let form_data = $("#booking_form").serialize()
                      $(document).find("span.text-danger").remove();
                      $.ajax({
                          url : "your-url",
                          type : "POST",
                          data : form_data,
                          success : function(response){
      
                          },
                          error:function (response){
                              $.each(response.responseJSON.errors,function(field_name,error){
                                  $(document).find('[name='+field_name+']').after('<span class="text-strong textdanger">' +error+ '</span>')
                              })
                          }
                      })
                  })
      

      【讨论】:

        【解决方案3】:

        试试这个代码。效果很好:

        $.ajaxSetup({
            headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
        });
        
        
        
        $("#sendData").submit(function(e) 
        {
            e.preventDefault();
            var formData  = new FormData(jQuery('#sendData')[0]);
            $.ajax({
        
               type:'POST',
               url:"/your(URL)",
               data:formData,
                contentType: false,
                processData: false,
               success:function(data)
               {
                  alert(data);
               },
                error: function(xhr, status, error) 
                {
        
                  $.each(xhr.responseJSON.errors, function (key, item) 
                  {
                    $("#errors").append("<li class='alert alert-danger'>"+item+"</li>")
                  });
        
                }
        
            });
        
        });
        

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
        【解决方案4】:

        我在 laravel 5.5 中使用这种方式处理它

        HTML代码

        <div class="form-group  padding">
          <label for="">Kalyan Mandap Name <span class="text-danger">*</span></label>
          <input type="text" class="form-control" placeholder="Enter Kalyan Mandap Name" id="mandapName" name="mandapName" value = "<?php echo (isset($mandapDetails['vchKalyanMandapName'])) ? $mandapDetails['vchKalyanMandapName'] : ""; ?>" required="required">
          <span class="text-danger">{!! $errors->first('mandapName', ':message') !!} </span>
        </div>
        

        控制器验证码

         // Validate form data
            $validatedData = request()->validate([
              'mandapName' => 'required',
              'location' => 'required',
              'landmark' => 'required',
              'description' => 'required',
              'contactNo' => 'required',
              'slug' => 'required',
              'functional' => 'required'
            ]);
        

        在 javascript 中

             $.ajax({
                //.....Your ajax configuration
                success: function (data) {
                    // Success code
        
                },
                error: function (request, status, error) {
                    $('[name="mandapName"]').next('span').html(request.responseJSON.errors.mandapName);
                    //.......
                }
            });
        

        【讨论】:

          【解决方案5】:

          Laravel 5 自动返回验证错误

          为此,您只需要做以下事情,

          控制器:

          public function methodName(Request $request)
          {
              $this->validate($request,[
                  'field-to-validate' => 'required'
              ]);
          
              // if it's correctly validated then do the stuff here
          
              return new JsonResponse(['data'=>$youCanPassAnything],200);
          }
          

          查看:

                   $.ajax({
                      type: 'POST',
                      url: 'url-to-call',
                      data: {
                          "_token": "{{ csrf_token() }}",
                          "field": $('#field').cal()
                      },
                      success: function (data) {
                          console.log(data);
                      },
                      error: function (reject) {
                          if( reject.status === 422 ) {
                              var errors = $.parseJSON(reject.responseText);
                              $.each(errors, function (key, val) {
                                  $("#" + key + "_error").text(val[0]);
                              });
                          }
                      }
                  });
          

          您可以为每个validation 字段构建一个&lt;span&gt; 标记,其中id 为字段名称,后缀为_error,因此它将显示验证错误,上述逻辑如下所示,

          <span id="field_error"></span>
          

          希望对你有帮助:)

          【讨论】:

          • 但是,例如,如果我更正了一个错误并再次单击,我如何才能删除那条曾经是错误但现在已更正的特定消息?
          • @MarcoBozzola 如果响应失败,您需要删除所有消息并再次设置响应消息,否则一切正常。
          【解决方案6】:

          在使用 Ajax 请求时有更好的方法来处理验证错误。

          像往常一样创建一个Request类,例如UploadFileAjaxRequest

          public function rules()
          {
              return [
                  'file' => 'required'
              ];
          }
          

          在控制器方法中使用它:

          public function uploadFileAjax(UploadFileAjaxRequest $request)
          

          如果有任何错误,它将返回一个错误数组,您可以在 JS 中使用:

          $.ajax({
              ....
              error: function(data) {
                  var errors = data.responseJSON; // An array with all errors.
              }
          });
          

          【讨论】:

            【解决方案7】:

            顺便说一句,我使用的是 Laravel 5.1,但我认为它的基本原理应该适用于其他版本。 Laravel 会自动发回验证错误响应。 您可以在控制器中执行以下操作:

            public function processEmail(Request $request)
            {
                $this->validate($request, [
                    'email' => 'required|email'
                ]);
                return response()->json(['message'=>'success']);
            }
            

            然后在你的 javascript 中(我在这里使用 jQuery):

            var params = {email: 'get-from-form-input@test.com'};
            $.ajax({
                url: '/test/example',
                method: 'POST',
                data: params
            })
            .done(function( data ) {
                // do something nice, the response was successful
            })
            .fail(function(jqXHR, textStatus, errorThrown) {
                var responseMsg = jQuery.parseJSON(jqXHR.responseText);
                var errorMsg = 'There was a general problem with your request';
                if (responseMsg.hasOwnProperty('email')) {
                    errorMsg = responseMsg.email;
                    console.log(errorMsg);
                }
                // This will help you debug the response
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            });
            

            如果您查看控制台上的输出,您很快就会知道如何从 Laravel 发回的响应中获取您想要的任何内容。在该响应中,错误消息在 json 中作为键值对,其中键是验证失败的字段的名称,在我的示例中为“电子邮件”。 请记住确保在您的 routes.php 文件中设置了 ajax 路由,并且方法 (get/post) 与 javascript 中的匹配。

            【讨论】:

              【解决方案8】:

              最简单的方法是利用验证器的MessageBag 对象。可以这样完成:

              // Setup the validator
              $rules = array('username' => 'required|email', 'password' => 'required');
              $validator = Validator::make(Input::all(), $rules);
              
              // Validate the input and return correct response
              if ($validator->fails())
              {
                  return Response::json(array(
                      'success' => false,
                      'errors' => $validator->getMessageBag()->toArray()
              
                  ), 400); // 400 being the HTTP code for an invalid request.
              }
              return Response::json(array('success' => true), 200);
              

              这会给你一个像这样的 JSON 响应:

              {
                  "success": false,
                  "errors": {
                      "username": [
                          "The username field is required."
                      ],
                      "password": [
                          "The password field is required."
                      ]
                  }
              }
              

              【讨论】:

              • 这可能是一个愚蠢的评论 - 但不将 http 代码设置为 400 意味着 JSON 响应被完全忽略了吗?
              • 取决于读取 JSON 的“客户端”。例如,jQuery 可以很好地处理这个问题。它不会触发成功,而是错误回调,这就是你想要的。
              • 使用 jQuery,您可以在 ajax 请求中使用此代码获取错误:error: function(xhr, status, data){ console.log(xhr.responseJSON.errors); }
              • 谢谢。您知道如何修改响应以每个字段返回一个字符串而不是数组吗?我试图在一个字段中获取多个错误字符串,但似乎不可能。
              • @JCarlos 消息包将它们分组到一个数组中。您可以像这样映射项目:'errors' =&gt; array_map(function($fieldErrors) { return $fieldErrors[0]; }, $validator-&gt;getMessageBag()-&gt;toArray())
              【解决方案9】:

              在 ajax 响应中尝试类似

                  .fail(function( data ) {
                      var response = JSON.parse(data.responseText);
                      var errorString = '<ul>';
                      $.each( response.errors, function( key, value) {
                          errorString += '<li>' + value + '</li>';
                      });
                      errorString += '</ul>';
              

              【讨论】:

                猜你喜欢
                • 2018-10-22
                • 2020-04-30
                • 2017-12-11
                • 2017-11-12
                • 1970-01-01
                • 2020-03-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多