处理文件上传:使用Node.js和Express构建Web应用程序时,文件上传是一个常见的需求。在本教程中,您将学习如何使用Node.js和Express处理上传的文件。
注意:为了跟随本教程,您需要以下内容:
在您的计算机上安装Node.js
基本的JavaScript和Express知识
一个文本编辑器或轻量级IDE,如Visual Studio Code
概述
为了允许文件上传,您将:
创建一个包含表单的网页,允许用户选择要上传的文件
创建一个Express路由处理程序来处理上传的文件
当然,您还希望对每个上传的文件进行一些操作!在本教程中,我们将编写JavaScript代码来显示有关文件的一些信息,并使用Verisys Antivirus API扫描恶意软件。
Verisys Antivirus API是一种与语言无关的REST API,可以在边缘停止恶意软件 - 在它到达您的服务器之前。
通过扫描用户生成的内容和文件上传,Verisys Antivirus API可以阻止危险的恶意软件进入您的应用程序和服务 - 以及您的最终用户。
项目设置
第一步是创建和初始化一个新的Express项目。
打开一个终端或命令提示符,导航到您想要存储项目的目录,并运行以下命令:
npx express-generator --view=pug myapp
cd myapp
npm install
生成的应用程序应具有以下目录结构:
代码语言:js复制.
├── app.js
├── package.json
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
├── views
│ ├── error.pug
│ └── index.pug
│ └── layout.pug
在我们继续之前,请确保您能够运行该应用程序并在浏览器中查看它
在MacOS、Linux或Windows上的Git Bash中,使用以下命令运行应用程序:
DEBUG=myapp:* npm start
或者对于Windows,使用以下命令:
set DEBUG=myapp:* & npm start
或者对于Windows Powershell,使用以下命令:
$env:DEBUG='myapp:*'; npm start
然后在浏览器中导航到http://localhost:3000以访问该应用程序 - 您应该会看到一个像这样的页面:
随后,通过在命令提示符处按下CTRL-C来停止服务器
接下来,我们将添加几个NPM包:
我们将添加一个包,以更轻松地处理文件上传。这里有几个选择,最流行的是Multer、Formidable和express-fileupload - 它们都非常相似,对于本教程,我们将使用express-fileupload
对于本教程,我们将使用Verisys Antivirus API扫描文件以检测恶意软件,因此我们将添加一个包来更轻松地进行外部HTTP请求。流行的选择包括Axios和node-fetch - 对于本文,我们将使用node-fetch
我们还将添加form-data包,以允许使用multipart表单数据进行工作,这用于执行文件上传
代码语言:js复制npm install express-fileupload
npm install node-fetch@^2.6.6
npm install form-data
前端
在编写JavaScript代码处理文件上传之前,让我们创建一个简单的网页,让最终用户选择要上传的文件。
更新myapp/views/index.pug的内容如下:
代码语言:js复制extends layout
block content
h1= title
p 欢迎来到#{title}
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" required>
<button type="submit">上传</button>
</form>
当表单提交时,文件将被发送到/upload路由 - 下一步是创建路由和路由处理程序。
后端
现在,我们将添加一个路由处理程序来处理上传的文件,然后将处理程序连接到/upload路由。
创建文件myapp/routes/upload.js,并添加以下内容:
代码语言:javascript复制const express = require('express');
const fetch = require('node-fetch');
const fileUpload = require('express-fileupload');
const FormData = require('form-data');
const fs = require('fs');
const router = express.Router();
router.use(fileUpload({
// 配置文件上传,最大文件大小为10MB
limits: { fileSize: 10 * 1024 * 1024 },
// 将上传的文件暂时存储到磁盘,而不是在内存中缓冲
useTempFiles : true,
tempFileDir : '/tmp/'
}));
router.post('/', async function(req, res, next) {
if (!req.files || !req.files.file) {
return res.status(422).send('未上传文件');
}
const uploadedFile = req.files.file;
// 将文件的信息打印到控制台
console.log(`文件名:${uploadedFile.name}`);
console.log(`文件大小:${uploadedFile.size}`);
console.log(`文件MD5哈希:${uploadedFile.md5}`);
console.log(`文件Mime类型:${uploadedFile.mimetype}`);
// 使用Verisys Antivirus API扫描文件中的恶意软件 - 相同的概念可以用于以不同的方式处理上传的文件
try {
// 将上传的文件附加到一个FormData实例
var form = new FormData();
form.append('file_name', uploadedFile.name);
form.append('file', fs.createReadStream(uploadedFile.tempFilePath), uploadedFile.name);
const headers = {
'X-API-Key': '<YOUR API KEY HERE>',
'Accept': '*/*'
};
// 将文件发送到Verisys Antivirus API
const response = await fetch('https://eu1.api.av.ionxsolutions.com/v1/malware/scan/file', {
method: "POST",
body
: form,
headers: headers
});
// 我们从API获取到了响应吗?
if (response.ok) {
const result = await response.json();
// 文件包含病毒/恶意软件吗?
if (result.status === 'clean') {
return res.send('上传成功!');
} else {
return res.status(500).send('上传的文件包含恶意软件!');
}
} else {
throw new Error('无法扫描文件:' response.statusText);
}
} catch (error) {
// 将错误转发给Express错误处理程序
return next(error);
} finally {
// 删除上传的临时文件
fs.rm(uploadedFile.tempFilePath, () => {});
}
});
module.exports = router;
此处理程序首先将文件的信息打印到控制台,以便您可以查看接收到的内容。然后,它将文件上传到Verisys Antivirus API以扫描其中的恶意软件 - 请注意,X-API-Key将需要替换为真实的API密钥以进行真实文件的扫描。还没有API密钥?立即订阅!
更新myapp/app.js的内容如下:
代码语言:javascript复制var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var uploadRouter = require('./routes/upload');
var app = express();
// 设置视图引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/upload', uploadRouter);
// 捕获404并转发到错误处理程序
app.use(function(req, res, next) {
next(createError(404));
});
// 错误处理程序
app.use(function(err, req, res, next) {
// 仅在开发环境提供错误信息
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// 渲染错误页面
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
我们只添加了两行代码到Express生成器提供的默认代码中(上面第9行和第25行),告诉Express使用我们的upload.js路由器来处理/upload路由。
首先通过与之前相同的命令启动您的Node.js服务器
打开浏览器并导航到http://localhost:3000
浏览以选择文件并按上传按钮
如果一切设置正确,您应该会在控制台上看到有关文件的信息,并且在浏览器中看到的内容将取决于Verisys Antivirus API的响应。
成功的文件上传