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

eeq64g8w  于 2023-04-22  发布在  jQuery
关注(0)|答案(6)|浏览(187)

最近我一直试图解决一个问题,但没有运气,基本上我试图使用 AJAX 向服务器提交一个表单,表单中有文件,所以我使用JQuery 1.12中的FormData javascript对象。数据到达服务器,但我不知道如何格式化它。
这是我的 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 predicate 设置为POST。结果相同。
  • 设置 AJAX contentType: falsecontentType: application/json。空响应。
  • 删除enctype: 'multipart/form-data'。相同的响应。

任何帮助都很感激。

6tr1vspr

6tr1vspr1#

这个帮我修好了

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

processData: false防止jQuery解析数据并抛出Illegal Invocation错误。当jQuery遇到表单中的文件并且无法将其转换为字符串(序列化它)时,它会这样做。
contentType: false阻止 AJAX 发送内容类型头。内容类型头使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()排除文件

sycxhyv7

sycxhyv72#

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

我会尝试对这个问题进行更多的研究。

lokaqttq

lokaqttq3#

Laravel 7中,如果 AJAX 中使用PUT方法,可以按照1.将方法method: 'PUT'改为method: 'POST' 2.添加formdata.append with _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);
        }
    });
});

它对我很有效

idfiyjo8

idfiyjo84#

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

chhqkbe15#

有点晚了,但是;这会解决你的问题;

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

这是一种新的方法。不要给予:-)

nfeuvbwi

nfeuvbwi6#

如果你得到这样回应
Array([------WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:_form-data;_name] =〉“mencomentid”43 ------WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:form-data; name=“mmencomentid”39 -----WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:form-data; name=“replymencomment”asd ------WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:form-data; name=“video”-----WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:form-data; name=“file”;filename="”Content-Type:application/octet-stream ------WebKitFormBoundaryZHCPkXfouoiFpLDg Content-Disposition:form-data; name=“音频”;filename="”Content-Type:application/octet-stream -----WebKitFormBoundaryZHCPkXfouoiFpLDg--)
then cache:false,processData:false,contentType:假的,
添加这些内部请求可以帮助我

相关问题