教程 express tutorial

文件上传

文件上传是 Web 应用中常见的功能之一。Express 不自带处理文件上传的功能,但我们可以通过第三方中间件 multer 来轻松处理文件上传。multer 支持多种上传方式,包括单个文件上传、多个文件上传和文件大小限制等功能。

安装 multer

首先,我们需要安装 multer,它是 Express 的一个中间件,用于处理 multipart/form-data 格式的文件上传。

bash
npm install multer

`

配置 multer

multer 中间件需要一个存储引擎,用于决定文件存储的位置和文件名。multer 提供了两种存储方式:

  • 硬盘存储:将上传的文件存储到指定的文件夹。
  • 内存存储:将文件存储在内存中(适用于小文件的上传)。

1. 硬盘存储

如果我们希望将上传的文件存储到磁盘中,可以使用硬盘存储。

1.1 配置硬盘存储

js
const multer = require('multer');
const path = require('path');

// 配置存储引擎,指定文件保存路径和文件名
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');  // 文件存储的文件夹
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); // 为文件生成唯一名称
    cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
  }
});

// 创建 multer 实例,指定存储引擎
const upload = multer({ storage: storage });

1.2 处理文件上传

js
// 上传单个文件
app.post('/upload', upload.single('file'), (req, res) => {
  res.send(`文件上传成功!文件名:${req.file.filename}`);
});

upload.single('file') 用于上传单个文件,'file' 是表单中文件上传字段的名称。

1.3 测试上传表单

创建一个 HTML 表单,允许用户选择文件并上传:

html
<form action="/upload" method="POST" enctype="multipart/form-data">
  <label for="file">选择文件:</label>
  <input type="file" id="file" name="file" required />
  <br />
  <button type="submit">上传</button>
</form>

2. 内存存储

内存存储将上传的文件存储在内存中,而不是磁盘。适用于处理较小文件,且无需在服务器上长期存储的场景。

2.1 配置内存存储

js
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

2.2 处理文件上传

js
app.post('/upload', upload.single('file'), (req, res) => {
  console.log('文件内容:', req.file.buffer);  // req.file.buffer 存储文件的二进制内容
  res.send('文件上传成功!');
});

2.3 测试上传表单

HTML 表单与之前相同,用户上传文件时,服务器会将文件存储在内存中。

3. 上传多个文件

如果我们想同时上传多个文件,可以使用 upload.array() 方法。

3.1 配置上传多个文件

js
app.post('/uploads', upload.array('files', 3), (req, res) => {
  // req.files 是上传的多个文件数组
  console.log(req.files);
  res.send(`成功上传了 ${req.files.length} 个文件`);
});

upload.array('files', 3) 用于上传最多 3 个文件,其中 'files' 是表单中文件字段的名称。

3.2 测试上传多个文件的表单

html
<form action="/uploads" method="POST" enctype="multipart/form-data">
  <label for="files">选择文件:</label>
  <input type="file" id="files" name="files" multiple required />
  <br />
  <button type="submit">上传</button>
</form>

4. 限制文件大小

我们可以设置文件的大小限制,防止上传过大的文件。

4.1 设置文件大小限制

js
const upload = multer({
  storage: storage,
  limits: { fileSize: 2 * 1024 * 1024 }  // 限制文件大小为 2MB
});

如果文件大小超过限制,multer 会自动返回一个错误,表示文件太大。

5. 文件类型验证

为了确保上传的文件是用户期望的类型(例如,只允许上传图片),我们可以设置文件类型验证。

5.1 设置文件类型验证

js
const upload = multer({
  storage: storage,
  fileFilter: (req, file, cb) => {
    const fileTypes = /jpeg|jpg|png|gif/;
    const extname = fileTypes.test(path.extname(file.originalname).toLowerCase());
    const mimetype = fileTypes.test(file.mimetype);

    if (extname && mimetype) {
      return cb(null, true);  // 文件通过验证
    } else {
      cb(new Error('只允许上传图片文件!'), false);  // 文件不通过验证
    }
  }
});

6. 错误处理

如果文件上传过程中出现错误,例如文件类型不匹配或文件过大,multer 会返回一个错误。我们可以捕获并处理这些错误。

6.1 错误处理中间件

js
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    return res.status(400).send(`上传错误:${err.message}`);
  } else if (err) {
    return res.status(500).send('服务器错误');
  }
  next();
});

总结

在 Express 中处理文件上传非常简单,主要通过 multer 中间件来实现。我们可以根据需求配置不同的存储方式、文件类型验证和文件大小限制等。文件上传处理的核心步骤包括:

  • 配置 multer 存储引擎(硬盘存储或内存存储)。
  • 使用 upload.single() 或 upload.array() 方法处理单个文件或多个文件上传。
  • 可选择设置文件类型和大小限制。

通过这些配置,我们能够轻松地处理各种文件上传需求。