You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Express.js实现视频上传至MongoDB的API?

实现视频上传至MongoDB的API方案

核心前提

MongoDB的普通BSON文档最大仅支持16MB存储,视频文件通常远超这个限制,所以必须使用GridFS来存储大文件——它会自动将文件拆分为256KB的分片存储,同时保留文件的元数据。下面以Node.js + Express + Mongoose栈为例,给出具体实现步骤:


1. 环境依赖安装

首先安装所需的npm包:

npm install express mongoose multer multer-gridfs-storage
  • express: 搭建Web服务
  • mongoose: MongoDB的ODM框架
  • multer: 处理multipart/form-data类型的文件上传
  • multer-gridfs-storage: 基于multer的GridFS存储引擎

2. 初始化MongoDB连接与GridFS配置

创建db.js文件,配置数据库连接和GridFS存储:

const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const GridFsStorage = require('multer-gridfs-storage');

// MongoDB连接字符串
const mongoURI = 'mongodb://localhost:27017/video_upload_db';

// 连接数据库
const conn = mongoose.createConnection(mongoURI);

// 初始化GridFS
let gfs;
conn.once('open', () => {
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('videos'); // 指定存储视频的集合名
});

// 配置multer的GridFS存储引擎
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => {
    // 自定义文件元数据和存储信息
    return new Promise((resolve, reject) => {
      const filename = `${Date.now()}-${file.originalname}`;
      const fileInfo = {
        filename: filename,
        bucketName: 'videos', // 对应上面的GridFS集合名
        metadata: {
          uploader: req.user?.id, // 可选:存储上传用户ID(需结合权限验证)
          originalName: file.originalname
        }
      };
      resolve(fileInfo);
    });
  }
});

const upload = require('multer')({ storage });

module.exports = { conn, gfs, upload };

3. 编写视频上传API接口

创建routes/videos.js文件,实现上传接口:

const express = require('express');
const router = express.Router();
const { upload } = require('../db');

// POST /api/videos/upload - 上传视频
router.post('/upload', upload.single('video'), (req, res) => {
  // req.file包含上传后的文件元数据
  if (!req.file) {
    return res.status(400).json({ error: '未选择视频文件' });
  }
  res.status(200).json({
    message: '视频上传成功',
    fileId: req.file.id,
    filename: req.file.filename,
    originalName: req.file.metadata.originalName
  });
});

module.exports = router;

然后在主文件app.js中挂载路由:

const express = require('express');
const app = express();
const videoRoutes = require('./routes/videos');

app.use('/api/videos', videoRoutes);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`服务运行在端口${PORT}`));

4. 编写视频获取/播放API接口

在routes/videos.js中添加获取接口,支持流式返回视频:

const { gfs } = require('../db');

// GET /api/videos/:filename - 根据文件名获取视频
router.get('/:filename', (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    if (!file || file.length === 0) {
      return res.status(404).json({ error: '视频不存在' });
    }

    // 检查文件是否为视频类型
    if (file.contentType.startsWith('video/')) {
      // 创建可读流
      const readstream = gfs.createReadStream(file.filename);
      readstream.pipe(res);
    } else {
      res.status(400).json({ error: '不是视频文件' });
    }
  });
});

// 可选:根据文件ID获取视频
router.get('/id/:id', (req, res) => {
  gfs.files.findOne({ _id: req.params.id }, (err, file) => {
    if (!file || file.length === 0) {
      return res.status(404).json({ error: '视频不存在' });
    }

    if (file.contentType.startsWith('video/')) {
      const readstream = gfs.createReadStream(file._id);
      readstream.pipe(res);
    } else {
      res.status(400).json({ error: '不是视频文件' });
    }
  });
});

5. 关键注意事项

  • 文件校验:可以在multer的file配置中添加视频格式校验,只允许mp4、mov等格式:
    file: (req, file) => {
      const allowedTypes = ['video/mp4', 'video/mov', 'video/webm'];
      if (!allowedTypes.includes(file.mimetype)) {
        return reject(new Error('仅支持MP4、MOV、WEBM格式的视频'));
      }
      // ... 其余代码
    }
    
  • 性能优化:GridFS适合存储视频,但直接从MongoDB流式返回可能影响性能,建议配合CDN缓存已上传的视频,或者将视频存储到对象存储,仅在MongoDB中保存视频的元数据和访问链接。
  • 权限控制:上传和获取接口需添加用户身份验证(如JWT),确保只有授权用户能上传或访问特定视频。
  • 文件大小限制:在multer配置中设置文件大小上限,避免超大文件占用资源:
    const upload = require('multer')({ 
      storage,
      limits: { fileSize: 100 * 1024 * 1024 } // 限制100MB
    });
    

内容的提问来源于stack exchange,提问作者Arijit das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:45:30