如何使用Node.js和Express实现Web应用程序中的文件上传

2024-02-09 00:18:37 浏览数 (1)

处理文件上传:使用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的响应。

成功的文件上传

0 人点赞