【问题标题】:Laravel 5.4 not able to parse FormData javascript object sent using Jquery AjaxLaravel 5.4 无法解析使用 Jquery Ajax 发送的 FormData javascript 对象
【发布时间】:2018-01-12 05:10:59
【问题描述】:

最近我一直在尝试解决一个没有运气的问题,基本上我正在尝试使用 AJAX 向服务器提交表单,该表单有文件,所以我在 JQuery 中使用 FormData javascript 对象1.12。数据到达服务器,但我不知道如何格式化它。

这是我的 AJAX 函数:

function saveMenu(id){
    var formElement = document.getElementById("menu-form");
    var formData = new FormData(formElement);
    formData.append('_method', 'PUT');
    $( "#form-wrapper" ).toggleClass( "be-loading-active" );
    $.ajax({
        type: 'PUT',
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        url: "{{url('myUrl')}}",
        data: formData,
        enctype: 'multipart/form-data',
        processData: false,
        success: function(response) {
            toastr.success('Yai! Saved successfully!')
        },
        error: function(response) {
            toastr.error('Oh oh! Something went really wrong!')
        },
        complete: function() {
            $( "#form-wrapper" ).toggleClass( "be-loading-active" )
        }
    });
}

当我在我的控制器中执行dd($request->all()); 时,我会得到如下信息:

array:1 [
  "------WebKitFormBoundaryRCIAg1VylATQGx46\r\nContent-Disposition:_form-data;_name" => """
    "_token"\r\n
    \r\n
    jtv4bnn8WQnP3eqmKZV3xWka2YOpnNc1pgrIfk0D\r\n
    ------WebKitFormBoundaryRCIAg1VylATQGx46\r\n
    Content-Disposition: form-data; name="blocks[43][title]"\r\n
    \r\n
...

我尝试过的事情:

  • 将 HTTP 谓词设置为 POST。结果相同。
  • 设置AJAX contentType: falsecontentType: application/json。空响应。
  • 删除enctype: 'multipart/form-data'。相同的响应。

感谢任何帮助。

【问题讨论】:

  • 嗯.. 我会尝试在我的位置创建一个可行的实例。你试过这个 dd($request->_method) 吗?
  • @RomnickSusa 是的,它返回 null。
  • 删除nctype: 'multipart/form-data后是否删除了js缓存,因为我认为这是关键
  • @ThomasMoors 在我看来是一样的。
  • 如果您没有使用 1.9.0 之前的 jQuery 版本。 ,你应该把`type: 'PUT'`改为`method: 'PUT'`

标签: ajax laravel http laravel-5.4 form-data


【解决方案1】:

有点晚了,但是; 这将解决您的问题;

var formData = new FormData(document.getElementById('form'));
console.log(...formData);

var object = {};
formData.forEach(function (value, key) {
    object[key] = value;
});

然后您可以将此object 发送到服务器。这更具可读性并且效果很好。

你可以直接发送这个;

JSON.stringify(Object.fromEntries(formData));

这是较新的方法。 并且不要放弃:-)

【讨论】:

    【解决方案2】:

    Laravel 7, 如果在 ajax 中使用 PUT 方法,您可以按照 1.将方法method: 'PUT'改为method: 'POST' 2. 使用_method PUT 添加formdata.append,如下例:

    $('#updateBtn').click(function(e){
        e.preventDefault();
        var frm = $('#tambahForm');
        frm.trigger("reset");
        $('.edit_errorNama_kategori').hide();
        $('.edit_errorGambar').hide();
        var url = "/pengurus/category/"+$('#edit_id').val();
        var formdata = new FormData($("#editForm")[0]);
        formdata.append('_method', 'PUT');  //*** here
    
        $.ajax({                       
            method :'POST', //*** here
            url : url,
            data : formdata,
            dataType : 'json',
            processData: false,
            contentType: false,
            success:function(data){
              if (data.errors) {
                if (data.errors.nama_kategori) {
                    $('.edit_errorNama_kategori').show();
                    $('.edit_errorNama_kategori').text(data.errors.nama_kategori);
                }
                if (data.errors.gambar){
                  $('.edit_errorGambar').show();
                  $('.edit_errorGambar').text(data.errors.gambar);
                }
              }else {
                frm.trigger('reset');
                $('#editModal').modal('hide');
                swal('Success!','Data Updated Successfully','success');
                table.ajax.reload(null,false);
              }
            },
            error: function (jqXHR, textStatus, errorThrown) {
              alert('Please Reload to read Ajax');
              console.log("ERROR : ", e);
            }
        });
    });
    

    它对我有用

    【讨论】:

      【解决方案3】:

      这为我解决了问题

      data: form_data,
      contentType: false,
      processData: false,
      

      processData: false 阻止 jQuery 解析数据并抛出非法调用错误。 JQuery 在遇到表单中的文件并且无法将其转换为字符串(对其进行序列化)时会执行此操作。

      contentType: false 阻止 ajax 发送内容类型标头。内容类型标头使 Laravel 将 FormData 对象作为一些序列化字符串处理。

      将两者都设置为 false 使它对我有用。 我希望这会有所帮助。

      $('#my-form').submit(function(e) {
              e.preventDefault();
              var api_token = $('meta[name="api-token"]').attr('content');
              form_data = new FormData(this);
              $.ajax({
                  type: 'POST',
                  url: '/api/v1/item/add',
                  headers: {
                      Authorization: 'Bearer ' + api_token
                  },
                  data: form_data,
                  contentType: false,
                  processData: false,
                  success: function(result,status,xhr) {
                      console.log(result);
                  },
                  error: function(xhr, status, error) {
                      console.log(xhr.responseText);
                  }
              });
          });
      

      还记得使用$request->all(); $request->input() 排除文件

      【讨论】:

        【解决方案4】:

        最后我放弃了尝试让它工作并尝试了一种更普通的方法,我仍然不知道为什么请求格式是这样的,但是XMLHttpRequest() 函数可以完美运行并且迁移并不大交易。

        我发布的功能相当于:

        function saveMenu(action){
            var formElement = document.getElementById("menu-form");
            var formData = new FormData(formElement);
            formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
        
            var request = new XMLHttpRequest();
            request.open("POST", "{{url('myUrl')}}");
            request.send(formData);
        
            request.onload = function(oEvent) {
              if (request.status == 200) {
                toastr.success('Yai! Saved successfully!');
              } else {
                toastr.error('Oh oh! Something went really wrong!');
              }
              $( "#form-wrapper" ).toggleClass( "be-loading-active" );
            };
        }
        

        【讨论】:

          【解决方案5】:

          我已经尝试调试了 2 个小时,但我发现 PUT 方法无法正确使用 formData。

          尝试改变

          type : "PUT" 
          

          进入

          method : "POST"
          

          然后将您在后端的方法从put 更改为post,您就会看到不同之处。 我用下面的代码来测试它

          $("#menu-form").submit(function (){
              var fd = new FormData();
              fd.append('section', 'general');
              fd.append('action', 'previewImg');
              fd.append('new_image', $('.new_image')[0].files[0]); 
              $.ajax({
                  method : 'POST',
                  headers: {
                      'X-CSRF-TOKEN': '{{ csrf_token()}}'
                  },
                  url: "{{url('upload-now')}}",
                  data : fd,
                  contentType: false,
                  processData: false,
                  success: function(response) {
                      console.log(response);
                  },
              });
              return false;
          });
          

          在我的控制器中

          public function test(Request $request){
              dd($request->all());
          }
          

          我会尝试更多地研究这个问题。

          【讨论】:

          • 抱歉,我的表单比您可以轻松附加的 3 个输入更复杂,它有多个级别和更多文件。无论如何,我已经尝试更改为问题中所说的 POST 方法,但对我来说并没有改变。
          • 我稍后会修改我的答案
          • 我有一个解决方案,但我放弃了 jquery ajax 函数以支持XMLRequest()
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-21
          相关资源
          最近更新 更多