通过 AJAX 发送图像文件。 request.FILES 为空?

Posted

技术标签:

【中文标题】通过 AJAX 发送图像文件。 request.FILES 为空?【英文标题】:Sending image file via AJAX. request.FILES is empty? 【发布时间】:2019-03-22 08:21:00 【问题描述】:

我正在尝试使用 Ajax 发送图像数据。但是我在后端得到的request.FILES 是空的。我在表单中添加了multipart/form-data,方法是POST

这是我的 AJAX 调用:

 $(document).on('submit', '#profile_edit_form', function(event)

  event.preventDefault();


  $.ajax(
      url     : "/users/update_profile_info/",
      type    : 'post',
      dataType: 'json',
      data    : $(this).serialize(),
      success : function(data) 

        $('#profile_name_tag').html(data.username);
        $('#username_navbar').html(data.username);

        //SENDING THE IMAGE VIA AJAX HERE
        var img_data = $('#id_image').get(0).files;
        formdata = new FormData();
        formdata.append("img_data", img_data);

        $.ajax(
            url         : "/users/update_profile_image/",
            type        : 'POST',
            enctype     : "multipart/form-data",
            data        : formdata,
            cache       : false,
            contentType : false,
            processData : false,
            success : function(data) 
              console.log('success');
              //$('#profile_picture').html(data.)

            ,
            error: function(data) 
              console.log('fail');
            
        );

      ,
      error: function(data) 
          console.log('fail');
      
  );


);

这是我的表格:

   <form id="profile_edit_form" method="POST">
     % csrf_token %
     <fieldset class="form-group">
       <legend class="border-bottom mb4"> Profile Info </legend>
             u_form|crispy
            p_form|crispy
     </fieldset>
     <button class="btn btn-outline-info" type="submit"> Update Info </button>
   </form>

如您所见,我使用的是 cispy 表单。图片字段在p_form

这是我的django view

@login_required
def update_profile_image(request):
    print(not request.FILES)

    if request.method == 'POST':
        p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user)
        if p_form.is_valid():
            p_form.save()

            context = 'None': 'none'
            return JsonResponse(context)
        else:
            return HttpResponse('None')

print(not request.FILES)返回True,图片当然没有上传。

我检查了很多类似的问题。但在所有这些中,解决方案是将multipart/form-data 添加到我已经完成的表单中。 那么问题出在哪里?

谢谢!

【问题讨论】:

删除手动 enctype 设置,因为 jQuery 会为你做这件事。然后尝试var img_data = $('#id_image').get(0).files[0],因为files 是一个集合,append() 可能只需要一个文件。 @RoryMcCrossan 感谢您的建议。我按照你说的做了,但我仍然收到一个空请求。文件 只要第一个 AJAX 请求成功并且 #id_image 元素存在并包含文件,我看不出您的逻辑有什么特别错误。您能否向我们展示您尝试读取文件的 Django 代码。我不是 Django 专家,但我相信其他人可以为您检查它 $(this).serialize() 传递数据时要注意你的范围 @RoryMcCrossan 尝试 var var img_data = $('#id_image').get(0).files[0] 确实有效。把它写成答案,我会接受的。 【参考方案1】:

我把代码改成

var img_data = $('#id_image').get(0).files[0];
formdata = new FormData();
formdata.append("img_data", img_data);
//console.log(formdata.get("img_data"));

$.ajax(
    url         : "/users/update_profile_image/",
    type        : 'POST',
    //enctype     : "multipart/form-data",   //it is done inside jquery
    data        : formdata,
    cache       : false,
    contentType : false,
    processData : false,
    success : function(data) 
      console.log('success');
      //$('#profile_picture').html(data.)

    ,
    error: function(data) 
      console.log('image-fail');
    
);

终于成功了!

【讨论】:

【参考方案2】:

FormData.append() 需要一个实体时,您将整个 files 集合提供给它。

尝试只从 files 访问单个文件并传递它:

var img_data = $('#id_image').get(0).files[0]; // note [0]

我还建议删除enctype 设置,因为当您向请求提供FormData 对象时,jQuery 会自动为您执行此操作。手动设置值可能会用不正确的值覆盖设置。

【讨论】:

谢谢。使用您的建议和其他一些修改,它终于奏效了!

以上是关于通过 AJAX 发送图像文件。 request.FILES 为空?的主要内容,如果未能解决你的问题,请参考以下文章

通过 ajax 将 base64 图像数据发送到 cfc

通过 Ajax 将裁剪的图像数据发送到 PHP

使用 Ajax 将图像发送到 PHP

如何通过 ajax 将文件发送到 Django 服务器?

如何使用 Ajax 将图像发送到 PHP 文件?

未通过 AJAX POST 请求发送大尺寸图像的 base64(作为 FormData 参数)