如何将Canvas生成的图片上传至后端服务器?
问题描述
我有一个Canvas,原本用以下代码将生成的JPG图片下载到本地:
var a = document.createElement('a'); a.href = ref_canvas_release.current.toDataURL('image/jpeg', 0.85); a.download = GlobalParam.fileObj.project_name + '.jpg'; a.click();
现在想把图片上传到后端服务器而非下载,尝试了下面的代码但有错误:
fileimage = ref_canvas_release.current.toDataURL('image/jpeg', 0.85); const formData = new FormData(); // 这里的写法不正确 formData.append("myfile",fileimage); var url = '/get_thumbnail'; axios.post(url, formData, { headers: { "Content-Type": "multipart/form-data", }, }).then((res) =>{ console.log(res); });
我考虑或许不用生成文件,直接用字节流实现,但不清楚具体怎么做?
解决方案
你的问题核心是:toDataURL返回的是base64编码的字符串,而FormData.append需要的是Blob或File类型的二进制对象,直接传字符串后端无法识别为文件。下面提供两种可行的实现方式:
方法1:将base64字符串转换为Blob再封装成File对象
先解码base64字符串得到二进制数据,转成Blob后包装成File对象,再添加到FormData中:
const canvas = ref_canvas_release.current; const dataURL = canvas.toDataURL('image/jpeg', 0.85); // 解码base64为Blob的工具函数 const b64toBlob = (dataURL) => { const arr = dataURL.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type: mime}); }; const blob = b64toBlob(dataURL); const file = new File([blob], `${GlobalParam.fileObj.project_name}.jpg`, {type: 'image/jpeg'}); const formData = new FormData(); formData.append('myfile', file); axios.post('/get_thumbnail', formData) .then(res => { console.log(res); }) .catch(err => { console.error(err); });
方法2:直接使用Canvas的toBlob方法(推荐)
toBlob可以直接将Canvas内容转换为Blob,省去base64解码的步骤,性能更优:
const canvas = ref_canvas_release.current; canvas.toBlob((blob) => { const file = new File([blob], `${GlobalParam.fileObj.project_name}.jpg`, {type: 'image/jpeg'}); const formData = new FormData(); formData.append('myfile', file); axios.post('/get_thumbnail', formData) .then(res => { console.log(res); }) .catch(err => { console.error(err); }); }, 'image/jpeg', 0.85);
关键注意点
- 不要手动设置
Content-Type: multipart/form-data,axios会自动根据FormData生成包含正确边界值的请求头,手动设置反而会导致后端解析失败。 toBlob是异步方法,所有后续上传逻辑必须放在它的回调函数中执行。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

