nodejs环境下接收FormData数据的模块居多,但是正常原生是如何实现的?
模块实现转FormData的大多用的有 : multer
、connect-multiparty
等等
然而,搜索到的原生实现甚少。
下面代码即为nodejs原生实现接收post传参从formData里取值
前端代码 -> axios react
/* 前端使用 axios react */
var files = new FormData() //实例formdata
files.append('file',this.refs.file.files[0]) //添加要上传的文件 无关类型
Axios.post('/upload/file',files,config ) //接口post 发送请求 附送 上传文件 file
.then((res)=>{
console.log(res.data) // 上传成功返回
this.setState({img:`https://${res.data.data.Location}`})
})
.catch(err => {
console.log(err) // 上传失败 错误 返回
})
FormData
如图,数据请求时FormData是这样的,那么我们就需要拿到这些数据给他截取出来相应的数据
实际操作——nodejs 代码
let uuid = () => { //生成uuid方法
let s = [];
let hexDigits = "0123456789abcdef";
for (let i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
let uuid = s.join("");
return uuid;
}
router.post('/file', (req, res, next) => { //post请求 我这边用的是express router
req.setEncoding('binary');
let body = ''; // 文件数据
// 边界字符串
let boundary = req.headers['content-type'].split('; ')[1].replace('boundary=', '');
//接收post如data 流 buffer
req.on('data', function (d) {
body += d;
});
req.on('end', function () {
let file = querystring.parse(body, '\r\n', ':');
let fileInfo = file['Content-Disposition'].split('; ');
let fileName = '';
let ext = '';
for (let value in fileInfo) {
if (fileInfo[value].indexOf("filename=") != -1) {
fileName = fileInfo[value].substring(10, fileInfo[value].length - 1);
if (fileName.indexOf('\\') != -1) {
fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
}
ext = fileName.substr(fileName.indexOf('.') + 1, fileName.length);
}
}
let upperBoundary = body.toString().indexOf(file['Content-Type'].substring(1)) + file['Content-Type'].substring(1).length;
let binaryDataAlmost = body.toString().substring(upperBoundary).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
// 上传文件重命名
let uuidFileName = `${uuid()}.${ext}`
//上传文件 本地存放地址
let uploadDirFile = `./${uuidFileName}`
//创建文件流
let writerStream = fs.createWriteStream(uploadDirFile);
//开始 —— 写入文件到本地
writerStream.write(binaryDataAlmost.substring(0, binaryDataAlmost.indexOf(`--${boundary}--`)), 'binary');
//写入完成
writerStream.end();
writerStream.on('finish', function () {
console.log("写入完成。");
//删除刚刚创建好的本地文件 -> 只有在把文件存起来的时候需要删除掉本地,否则不要用。
fs.unlinkSync(uploadDirFile)
res.send({ data: data, code: 0, msg: 'ok' })
});
});
})
相对简单吧
直接复制粘贴即可用。