React上传signature_pad生成的SVG到Express时Multer返回undefined
问题根因
你调用signaturePad.toDataURL拿到的是base64编码的字符串,不是二进制文件对象。你使用的upload_file是multer的实例,它的single方法只会解析formData里的File/Blob类型字段,你传入的base64字符串会被multer当成普通表单字段存入req.body,自然req.file返回undefined。
解决方案
提供两种可落地的实现方案,按需选择即可:
方案1:前端转换格式,沿用现有multer配置
前端把base64字符串转成Blob对象后再传入formData,后端不需要做任何修改,原有逻辑直接生效。
前端修改后的代码如下:
// 新增base64转Blob工具方法 const dataURLtoBlob = (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}); } // 替换原有formData赋值逻辑 const svgBlob = dataURLtoBlob(signaturePad.toDataURL("image/svg+xml")); formData.append('contractId', contractId); // 第三个参数指定文件名,确保multer识别为文件 formData.append('svg_signature', svgBlob, 'signature.svg'); dispatch(sign_contract_action(formData));
方案2:后端直接处理base64,移除multer中间件
不需要修改前端代码,后端调整路由和存储逻辑即可:
- 首先修改路由配置,移除multer解析中间件
router.post('/sign-contract', save_svg_signature);
- 调整存储逻辑,直接解码base64写入文件
const fs = require('fs/promises'); const path = require('path'); const save_svg_signature = async (req,res,next) => { const { contractId, svg_signature } = req.body; // 移除base64前缀 const base64Content = svg_signature.replace(/^data:image\/svg\+xml;base64,/, ''); // 自定义存储路径 const savePath = path.join(__dirname, `./signature_files/${contractId}.svg`); // 写入文件 await fs.writeFile(savePath, base64Content, 'base64'); // 后续业务逻辑自行补充 };
内容的提问来源于stack exchange,提问作者nikola
相关产品推荐
相关产品推荐

