700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > node+multiparty接受formdata上传文件保存在硬盘

node+multiparty接受formdata上传文件保存在硬盘

时间:2022-05-17 05:25:39

相关推荐

node+multiparty接受formdata上传文件保存在硬盘

前言之前想起一个专门接受文件保存到本地的node服务,查遍了全网大部分都是浅尝辄止,点到为止。胡乱贴两段代码完事。经过一段时间的摸索写了一个完整可用的服务,希望能为有相关需要的开发提供一点思路。

效果

我们前端传输文件一般采用formdata的格式,所以服务端的核心在于怎样去解析formdata格式的数据,目前比较流行的解析插件主要有multipartybusboy,但我看了下大部分的资料都是围绕multiparty的,所以我这边也是采用multiparty进行数据解析。

multiparty官方文档

在引入插件

npm install multiparty

后,最简单的方法就是直接将需要保存文件的路径传入插件,即可自动解析保存(注意文件路径必须存在不然会报错)

(req, res)=>{var form = new multiparty.Form({uploadDir:'保存文件的地址'})// 进行解析form.parse(req)}

但这种方法插件会将文件先保存到内存然后在从内存保存到硬盘,我们可以直接通过创建来将数据写入硬盘。

监听part事件

Emitted when a part is encountered in the request. part is aReadableStream. It also has the following propertie

获取文件可读流,然后根据文件路径创建写入流,然后将文件流写入。

完整代码

const express = require('express');const multiparty = require('multiparty');const app = express();const fs = require('fs');const path = require('path')const Busboy = require('busboy');app.get('/', (req, res) => {res.send('hello, this is a node server for upload file current env is' + process.env.NODE_ENV)})// 跨域app.use(function (req, res, next) {if (req.method == 'OPTIONS') res.send('OPTIONS PASS')res.append('Access-Control-Allow-Origin', '*')res.append('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE')res.append('Access-Control-Allow-Headers', '*')next();});// 上传app.post('/upload', (req, res) => {const form = new multiparty.Form();try {form.on('part', async function (part) {if (part.filename) {// 获取上传路径const p = await new Promise((resolve, reject) => {form.on('field', (name, value) => {resolve(name == 'path'?value:'')})})const saveTo = (process.env.NODE_ENV == 'dev' ? 'D://Temp' : '/usr/static') + (p || '/default')// 如果不存在文件夹路径则创建文件夹await new Promise((resolve, reject) => {fs.stat(saveTo, (err) => {if (err) {fs.mkdirSync(saveTo);}resolve()})})// 根据路径创建写入流const writeStrem = fs.createWriteStream(path.join(saveTo, part.filename))part.pipe(writeStrem)}part.on('error', function (err) {fileStrem.destroy();});});form.parse(req)} catch (e) {console.log(e)res.send('500')}res.send('200')})app.listen(8010, function () {console.log('Example app listening on port 8010!\n');});

使用busboy同理,也是将文件流进行写入

const express = require('express');const multiparty = require('multiparty');const app = express();const fs = require('fs');const path = require('path')const Busboy = require('busboy');app.get('/', (req, res) => {res.send('hello, this is a node server for upload file current env is' + process.env.NODE_ENV)})// 跨域app.use(function (req, res, next) {if (req.method == 'OPTIONS') res.send('OPTIONS PASS')res.append('Access-Control-Allow-Origin', '*')res.append('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE')res.append('Access-Control-Allow-Headers', '*')next();});// 上传app.post('/upload', (req, res) => {// const form = new multiparty.Form();// try {//form.on('part', async function (part) {// if (part.filename) {// // 获取上传路径// const p = await new Promise((resolve, reject) => {// form.on('field', (name, value) => {// resolve(name == 'path'?value:'')// })// })// const saveTo = (process.env.NODE_ENV == 'dev' ? 'D://Temp' : '/usr/static') + (p || '/default')// // 如果不存在文件夹路径则创建文件夹// await new Promise((resolve, reject) => {// fs.stat(saveTo, (err) => {// if (err) {//fs.mkdirSync(saveTo);// }// resolve()// })// })// // 根据路径创建写入流// const writeStrem = fs.createWriteStream(path.join(saveTo, part.filename))// part.pipe(writeStrem)// }// part.on('error', function (err) {// fileStrem.destroy();// });//});//form.parse(req)// } catch (e) {//console.log(e)//res.send('500')// }const busboy = new Busboy({headers: req.headers });busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {var saveTo = path.join('D://Temp', path.basename(filename));file.pipe(fs.createWriteStream(saveTo));});busboy.on('finish', function() {res.writeHead(200, {'Connection': 'close' });res.end("That's all folks!");});return req.pipe(busboy); })app.listen(8010, function () {console.log('Example app listening on port 8010!\n');});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。