如何在Node.js和Express中上传文件


大量的移动应用程序和网站允许用户上传个人资料图片和其他文件。 因此,在使用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服务器

安装所需的依赖项之后,让我们开始创建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文件夹中。

express-fileupload中间件如何工作?

它使上传的文件可从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请求:

1. 单文件

Single File

2. 多个文件

多个文件
如果您想使上传的文件可以从任何地方公开访问,只需将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😍

阅读下一篇:使用Node.js中的Multer快速上传文件

相关博客链接

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 安装express和multer ``` npm install express multer --save ``` 2. 引入依赖 ``` const express = require('express') const multer = require('multer') const path = require('path') ``` 3. 创建express实例 ``` const app = express() ``` 4. 配置multer ``` const storage = multer.diskStorage({ // 设置上传后文件路径,uploads文件夹会自动创建。 destination: function (req, file, cb) { cb(null, 'uploads/') }, // 给上传文件重命名,获取添加后缀名 filename: function (req, file, cb) { const extname = path.extname(file.originalname) cb(null, Date.now() + extname) } }) const upload = multer({ storage: storage }) ``` 5. 创建路由 ``` // 单文件上传 app.post('/upload', upload.single('file'), (req, res, next) => { const file = req.file if (!file) { const error = new Error('Please upload a file') error.httpStatusCode = 400 return next(error) } res.send(file) }) // 多文件上传 app.post('/uploads', upload.array('files', 12), (req, res, next) => { const files = req.files if (!files) { const error = new Error('Please upload files') error.httpStatusCode = 400 return next(error) } res.send(files) }) ``` 6. 启动服务 ``` app.listen(3000, () => { console.log('Server started on port 3000') }) ``` 完整代码如下: ``` const express = require('express') const multer = require('multer') const path = require('path') const app = express() const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') }, filename: function (req, file, cb) { const extname = path.extname(file.originalname) cb(null, Date.now() + extname) } }) const upload = multer({ storage: storage }) app.post('/upload', upload.single('file'), (req, res, next) => { const file = req.file if (!file) { const error = new Error('Please upload a file') error.httpStatusCode = 400 return next(error) } res.send(file) }) app.post('/uploads', upload.array('files', 12), (req, res, next) => { const files = req.files if (!files) { const error = new Error('Please upload files') error.httpStatusCode = 400 return next(error) } res.send(files) }) app.listen(3000, () => { console.log('Server started on port 3000') }) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值