You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将dataURI转换为文件后通过Django REST Framework接口上传无效(返回200但未替换图片),但普通文件字段上传正常的问题求助

解决DRF接口无法接收裁剪后图片的问题

我一眼就看到了问题所在——你手动设置了Content-Type: multipart/form-data,这是导致后端无法正确解析上传文件的关键原因。

核心问题解析

当使用FormData作为fetch请求的body时,浏览器会自动生成正确的Content-Type头,其中包含一个自动生成的boundary(分隔符),用来分割FormData中的各个字段。如果你手动设置Content-Type: multipart/form-data,会丢失这个重要的boundary参数,导致Django后端无法正确解析表单数据——虽然返回200状态,但实际上并没有处理上传的文件。

修正后的代码

下面是调整后的完整代码,重点移除了手动设置的Content-Type,同时优化了一些细节:

uploadPhoto(context, dataURIimage) {
  const blob = dataURItoBlob(dataURIimage);
  // 确保文件类型和dataURI中的MIME类型一致
  const mimeString = dataURIimage.split(',')[0].split(':')[1].split(';')[0];
  const resultFile = new File([blob], "picture.png", { type: mimeString });
  const formData = new FormData();
  // 确认这里的键名"image"和后端DRF视图中接收的字段名完全一致
  formData.append("image", resultFile);
  
  const headerToken = "Token " + this.getters.getToken;
  const url = `https://workserver-7e6s4.ondigitalocean.app/api/people/${this.getters.getProfiel.id}/upload_image/`;
  
  fetch(url, {
    method: "POST",
    headers: {
      // 移除手动设置的Content-Type!
      'Authorization': headerToken,
    },
    body: formData,
    // 如果是跨域请求,可根据需求添加credentials配置
    // credentials: 'include',
  })
  .then(function(response) {
    console.log(response.status)
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(function(data) {
    console.log("上传成功,返回数据:", data.image);
    // 这里可同步更新本地头像显示,保持UI一致
  })
  .catch(function(error) {
    console.error("上传失败:", error);
    alert("图片上传失败,请重试");
  });
},

function dataURItoBlob(dataURI) {
  const [metaPart, dataPart] = dataURI.split(',');
  const mimeString = metaPart.split(':')[1].split(';')[0];
  let byteString;
  
  // 兼容URL编码格式的dataURI
  if (metaPart.includes('base64')) {
    byteString = atob(dataPart);
  } else {
    byteString = decodeURI(dataPart);
  }
  
  const ab = new ArrayBuffer(byteString.length);
  const ia = new Uint8Array(ab);
  
  for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  
  return new Blob([ab], { type: mimeString });
}

额外检查点

  1. 确认后端字段名:确保DRF视图中接收文件的字段名是image(和formData.append("image", resultFile)中的键一致),如果后端用的是其他名字(比如picture),需要对应修改。
  2. 验证File对象有效性:可以添加console.log(resultFile),查看文件的大小、类型是否符合预期,确保裁剪后的图片数据正常。
  3. 后端调试:如果仍有问题,可在DRF视图中打印request.FILES,确认是否接收到文件:
    # DRF视图中添加调试代码
    print(request.FILES)  # 正常情况下应能看到上传的image文件
    

这样修改后,浏览器会自动生成正确的multipart/form-data请求头,后端就能正常解析并处理上传的裁剪图片了。

内容的提问来源于stack exchange,提问作者MDekker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:42:31