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

React JS(Fetch)实现文件上传求助(后端为Django)

使用React的Fetch API实现文件上传(Django后端)

问题描述

我希望用React JS的Fetch API实现文件上传功能,已经通过Postman设置请求头application/x-www-form-urlencoded成功完成上传,现在需要用JS代码实现。我的代码如下:

function FileOnChange(e){
      let file=e.target.files;
      let reader = new FileReader();
      reader.readAsArrayBuffer(file[0])
                reader.onload = function () {
                    var data = reader.result;
                    //var array = new Int8Array(data);
                        var headers={
                        'Content-Type':'application/x-www-form-urlencoded',
                        'authorization':token
                    }   
                     const url=`${SITE}api/upload_avatar_profile/`;
                    fetch(url,{
                      method:'PUT',
                      headers:headers,
                      body:{
                          avatar:file[0]
                      }
                    }).then((response)=>{
                        return response.json();
                    }).then((data)=>{
                          
                       console.log(data)
                            });
                };
    }

后端基于Django,请求帮助。

解决方案

你的代码存在几个关键问题,针对application/x-www-form-urlencoded类型的请求,需要做以下调整:

  • 移除多余的FileReader操作:原代码中用readAsArrayBuffer读取文件是不必要的,这种格式需要的是URL编码的文本数据而非二进制数组。
  • 正确处理文件编码:application/x-www-form-urlencoded不支持直接传输二进制文件,需要将文件转为Base64编码后再放入请求体(Postman能成功是因为它自动完成了编码转换)。
  • 规范构造请求体:使用URLSearchParams自动处理URL编码,避免手动拼接时出现格式错误。

修改后的代码如下:

function FileOnChange(e) {
  const file = e.target.files[0];
  if (!file) return;

  // 将文件转换为Base64编码
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = function () {
    // 提取纯Base64内容(去除前缀"data:image/png;base64,")
    const base64Data = reader.result.split(',')[1];
    const headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      'authorization': token
    };
    const url = `${SITE}api/upload_avatar_profile/`;

    // 构造URL编码的表单数据
    const formData = new URLSearchParams();
    formData.append('avatar', base64Data);

    fetch(url, {
      method: 'PUT',
      headers: headers,
      body: formData
    })
    .then((response) => {
      if (!response.ok) throw new Error('上传请求失败');
      return response.json();
    })
    .then((data) => {
      console.log('上传成功:', data);
    })
    .catch((error) => {
      console.error('上传出错:', error);
    });
  };
}

更优方案:使用multipart/form-data

如果Django后端支持multipart/form-data类型的文件上传,更推荐使用这种标准文件上传格式,它处理二进制文件更高效,代码也更简洁:

function FileOnChange(e) {
  const file = e.target.files[0];
  if (!file) return;

  const formData = new FormData();
  formData.append('avatar', file);

  const headers = {
    'authorization': token
    // 无需手动设置Content-Type,浏览器会自动添加带边界标识的multipart/form-data头
  };
  const url = `${SITE}api/upload_avatar_profile/`;

  fetch(url, {
    method: 'PUT',
    headers: headers,
    body: formData
  })
  .then((response) => {
    if (!response.ok) throw new Error('上传请求失败');
    return response.json();
  })
  .then((data) => {
    console.log('上传成功:', data);
  })
  .catch((error) => {
    console.error('上传出错:', error);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:14:59