大量的移动应用程序和网站允许用户上传个人资料图片和其他文件。 因此,在使用Node.js和Express构建REST API时,通常需要处理文件上传。
在本教程中,我们将讨论如何使用Node.js和Express后端处理单个和多个文件上传,以及如何将上传的文件保存在服务器上。
首先,让我们通过运行以下命令来创建一个新的Node.js应用程序。 我正在使用npm
进行软件包管理。 如果愿意,可以使用yarn
。
# creat a new directory & switch to it
$ mkdir files-upload && cd files-upload
# run this for npm to create a new app
$ npm init -y
# run this for yarn to create a new app
$ yarn init -y
-y
或--yes
跳过交互会话,并根据默认设置生成package.json
文件。 接下来,运行以下命令以安装必需的依赖项:
# run this for npm
$ npm install express body-parser cors express-fileupload morgan lodash --save
# or using yarn
$ yarn add express body-parser cors express-fileupload morgan lodash
以下是上述每个软件包的功能:
express
-基于Node.js构建的流行Web框架。 我们将使用它来开发REST API。body-parser
-Node.js请求主体解析中间件,该中间件在处理程序之前解析传入的请求主体,并使其在req.body属性下可用。 简而言之,它简化了传入请求。cors
-另一种Express中间件,用于启用CORS(跨域资源共享)请求。express-fileupload
-用于上传文件的Simple Express中间件。 它解析multipart/form-data
请求,提取文件(如果有),并在req.files
属性下使它们可用。morgan
-用于记录HTTP请求的Node.js中间件。lodash
-一个JavaScript库,为数组,数字,对象,字符串等提供实用程序功能。安装所需的依赖项之后,让我们开始创建Express服务器。
index.js
const express = require('express');
const fileUpload = require('express-fileupload');
const cors = require('cors');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const _ = require('lodash');
const app = express();
// enable files upload
app.use(fileUpload({
createParentPath: true
}));
//add other middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(morgan('dev'));
//start app
const port = process.env.PORT || 3000;
app.listen(port, () =>
console.log(`App is listening on port ${port}.`)
);
上面的代码很容易理解。 它首先设置express-fileupload
中间件以启用multipart/form-data
请求。 之后,添加了其他Express中间件以允许跨域资源共享(CORS),请求正文解析和HTTP请求日志记录。 最后,它将在端口3000
上启动服务器。
让我们创建第一个路由,该路由允许用户上传其个人资料图片。
app.post('/upload-avatar', async (req, res) => {
try {
if(!req.files) {
res.send({
status: false,
message: 'No file uploaded'
});
} else {
//Use the name of the input field (i.e. "avatar") to retrieve the uploaded file
let avatar = req.files.avatar;
//Use the mv() method to place the file in upload directory (i.e. "uploads")
avatar.mv('./uploads/' + avatar.name);
//send response
res.send({
status: true,
message: 'File is uploaded',
data: {
name: avatar.name,
mimetype: avatar.mimetype,
size: avatar.size
}
});
}
} catch (err) {
res.status(500).send(err);
}
});
上面的代码段是一个HTTP POST
函数。 当您向/upload-avatar
路由发送multipart/form-data
请求以上传文件时,此功能会将文件保存到服务器上的uploads
文件夹中。
它使上传的文件可从req.files
属性访问。 例如,如果您上传名为my-profile.jpg
的文件,并且您的字段名是avatar
,则可以通过req.files.avatar
访问它。 avatar
对象将包含以下信息:
avatar.name
-上传文件的名称,即my-profile.jpg
avatar.mv
-将文件移动到服务器上其他位置的功能avatar.mimetype
-文件的mime类型avatar.size
-文件大小,以字节为单位avatar.data
-上载文件的缓冲区表示让我们开始创建另一条路由,以允许用户一次上传多张照片。
app.post('/upload-photos', async (req, res) => {
try {
if(!req.files) {
res.send({
status: false,
message: 'No file uploaded'
});
} else {
let data = [];
//loop all files
_.forEach(_.keysIn(req.files.photos), (key) => {
let photo = req.files.photos[key];
//move photo to uploads directory
photo.mv('./uploads/' + photo.name);
//push file details
data.push({
name: photo.name,
mimetype: photo.mimetype,
size: photo.size
});
});
//return response
res.send({
status: true,
message: 'Files are uploaded',
data: data
});
}
} catch (err) {
res.status(500).send(err);
}
});
上面的代码与单文件上传非常相似,除了我们现在收到的是photos
字段而不是avatar
。 我们使用lodash
实用程序函数(_.forEach()
和_.keysIn()
)遍历photos
字段,然后将每张照片保存到uploads
目录。
我们快完成了! 在终端的项目根目录中运行以下命令以启动应用程序:
$ node index.js
它将在端口3000
上启动应用程序。让我们使用Postman发送HTTP multipart/form-data
请求:
如果您想使上传的文件可以从任何地方公开访问,只需将uploads
目录设置为静态:
app.use(express.static('uploads'));
现在,您可以直接在浏览器中打开上传的文件:
http://localhost:3000/icon.png
如果要限制一次上传的文件的大小,请将limits
选项直接传递给express-fileupload
中间件:
app.use(fileUpload({
createParentPath: true,
limits: {
fileSize: 2 * 1024 * 1024 * 1024 //2MB max file(s) size
},
}));
源代码:在MIT许可下从GitHub下载完整的源代码。
那是所有! 我们学习了如何使用Node.js和Express框架上传单个和多个文件。 ·express-fileupload·是一种易于使用的Express中间件,用于处理文件上传。 查看其文档以获取更多配置选项。
如果您有任何疑问或反馈,请随时给我发送tweet。
快乐学习Node.js