Laravel 5.4 无法解析使用 Jquery Ajax 发送的 FormData javascript 对象

Laravel 5.4 not able to parse FormData javascript object sent using Jquery Ajax

最近我一直在尝试解决一个没有成功的问题,基本上我是在尝试使用 AJAX 向服务器提交一个表单,该表单有文件,所以我正在使用 FormData javascript JQuery 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
...

我尝试过的事情:

感谢任何帮助。

我已经尝试调试了 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());
}

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

最后我放弃了尝试让它工作并尝试了更普通的方法,我仍然不知道为什么请求是这样格式化的原因,但是 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" );
    };
}

这帮我修好了

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

processData: false 阻止 jQuery 解析数据并抛出非法调用错误。 JQuery遇到表单中的文件不能转成字符串(序列化)时就这样做

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

将两者都设置为 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()排除文件

Laravel 7, 如果使用 ajax 中的 PUT 方法,你可以按照 1. 将方法 method: 'PUT' 更改为 method: 'POST' 2. 添加 formdata.append 和 _method PUT 就像这个例子:

$('#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);
        }
    });
});

对我有用

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

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));

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