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
相关产品推荐
相关产品推荐

