《Node.js Express 实战:简易文件上传服务开发》

举报
JiHua 发表于 2026/10/13 10:05:00 2026/10/13
【摘要】 本文使用 Node.js + Express + multer 开发轻量本地文件上传服务,无需复杂数据库,实现单文件上传、大小限制、文件类型校验、上传列表查询功能。讲解中间件原理、安全校验要点,附带完整可运行代码,适合后端新手动手实践,可直接部署在华为云ECS进行测试。

前言

在后端开发中,文件上传是非常高频的业务场景:头像上传、文档提交、图片素材管理等业务都离不开该能力。很多初学者一开始就直接上手云存储SDK,忽略本地文件上传底层逻辑。本文不引入复杂组件,使用 Express + multer 快速搭建一个基础文件上传服务,理解文件接收、校验、存储的完整流程。

注意:本项目为学习演示项目,生产环境需要增加更多安全策略,同时建议搭配对象存储服务,不要直接在服务器磁盘大量存放用户文件。

技术栈介绍

  • Node.js:后端运行环境
  • Express:轻量 Web 框架,快速搭建 HTTP 服务
  • multer:Node.js 生态专门处理 multipart/form-data 表单文件上传的中间件
  • fs / path:Node.js 内置模块,用于文件路径处理与目录操作

项目初始化

新建项目文件夹,执行初始化命令:

# 初始化package.json
npm init -y
# 安装依赖
npm install express multer

在项目根目录创建 uploads 文件夹,用来存放上传后的文件。

完整代码 index.js

const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

const app = express();
const port = 3000;

// 配置上传存储规则
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    // 时间戳+原始文件名,防止重名覆盖
    const uniqueName = Date.now() + '-' + file.originalname;
    cb(null, uniqueName);
  }
})

// 文件过滤:只允许图片类型
const fileFilter = (req, file, cb) => {
  const allowTypes = ['image/jpeg', 'image/png', 'image/gif'];
  if (allowTypes.includes(file.mimetype)) {
    cb(null, true);
  } else {
    cb(new Error('仅支持 jpg/png/gif 图片上传'), false);
  }
}

// multer实例:限制单文件最大5MB
const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: { fileSize: 5 * 1024 * 1024 }
})

// 单文件上传接口,字段名avatar
app.post('/upload', upload.single('avatar'), (req, res) => {
  res.json({
    code: 200,
    msg: '上传成功',
    data: {
      filename: req.file.filename,
      path: `/uploads/${req.file.filename}`,
      size: req.file.size
    }
  })
})

// 获取上传文件列表接口
app.get('/file/list', (req, res) => {
  fs.readdir('uploads', (err, files) => {
    if(err) {
      return res.json({code:500, msg:'读取目录失败'})
    }
    res.json({code:200, data: files})
  })
})

// 静态资源访问,可直接访问上传图片
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// 全局错误捕获
app.use((err, req, res, next) => {
  res.json({code:400, msg: err.message})
})

app.listen(port, () => {
  console.log(`服务启动成功,监听端口 ${port}`);
})

代码核心讲解

  1. Storage 存储配置
    diskStorage 用来定义文件保存目录与文件名策略。这里使用时间戳拼接原始文件名,避免同名文件互相覆盖。真实业务中,还可以使用UUID生成文件名。

  2. 文件校验
    fileFilter 对文件 MIME 类型做校验,过滤非图片文件;limits 设置文件大小上限,防止超大文件占用服务器存储与带宽,这是上传接口最基础的安全防护。很多线上漏洞就是因为缺少文件大小、类型校验,导致恶意文件上传。

  3. 接口说明

  • POST /upload:单文件上传接口,表单字段名称固定为 avatar,上传成功返回文件信息;
  • GET /file/list:读取uploads目录,返回已经上传的文件清单;
  • express.static 将上传目录暴露为静态资源,上传图片后可以直接通过url访问。

本地测试

启动服务:

node index.js

推荐使用 Postman / Apifox 测试:请求方式 POST,地址 [http://127.0.0.1:3000/upload](http://127.0.0.1:3000/upload),body选择form-data,key填写avatar,类型选择文件,选择一张图片提交。上传成功后,浏览器访问 [http://127.0.0.1:3000/uploads/xxx.jpg](http://127.0.0.1:3000/uploads/xxx.jpg) 即可查看图片。访问 /file/list 获取全部上传文件。

实战踩坑总结

  1. 目录不存在报错:multer不会自动创建uploads文件夹,必须手动新建,否则上传直接报错。生产代码可以加fs判断目录是否存在,不存在自动创建。
  2. 安全风险提醒
    本示例仅用于学习。直接把用户文件存服务器磁盘存在风险:
  • 不要允许上传 .js、.php 等脚本文件,防止恶意代码执行;
  • 生产环境建议使用华为云对象存储OBS替代本地磁盘存储;
  • 增加请求频率限流,防止大量请求刷满服务器存储。

生产优化方向

  1. 增加JWT鉴权,上传接口需要登录才能调用;
  2. 增加接口限流,使用 express-rate-limit;
  3. 接入对象存储,文件直传OBS,服务器只负责业务逻辑;
  4. 增加文件删除接口;
  5. 数据库记录上传文件元信息,替代读取本地文件列表。

总结

文件上传是后端开发的基础能力,通过这个小型项目,我们掌握 multer 中间件使用、文件校验、静态资源托管等知识点。代码量不大,但覆盖了后端接收文件的完整流程。在学习完成之后,可以尝试将该项目部署到华为云ECS公网环境,对外提供上传测试服务,加深云服务器部署实践经验。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。