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

在Vercel的Express.js服务器上使用Multer存储图片失败问题排查

问题排查与解决方案

核心原因分析

  1. Vercel无服务器环境的临时存储限制
    Vercel的Node.js函数运行在临时容器中,容器的本地磁盘是短暂且非持久化的。Multer的diskStorage将文件写入本地uploads目录后,容器在函数执行完毕就会被销毁,文件也会被清理——日志显示“已处理”只是函数执行时临时写入了,后续马上被删除,自然无法通过静态路径访问。

  2. vercel.json路由配置无效
    当前路由规则{"src": "uploads/(.*)", "dest": "uploads/$1"}试图指向本地uploads目录,但Vercel部署时:

  • 若本地uploads目录为空,Git不会跟踪空目录,部署后该目录不存在;
  • 即使目录存在,动态上传的文件也不会被持久化,所以这个路由本质无法访问到上传的文件。
  1. Express静态服务适配问题
    app.use('/uploads', express.static('uploads'))在本地开发时有效,但在Vercel环境中,uploads目录的文件无法持久保存,静态服务自然找不到文件。

具体解决方案

1. 替换磁盘存储为持久化云存储(推荐)

放弃Multer的diskStorage,改用Vercel官方的Vercel Blob或第三方云存储(如Cloudinary、AWS S3)来存储上传的图片,步骤如下:

  • 安装Vercel Blob SDK:
    npm install @vercel/blob
    
  • 修改Multer配置为内存存储,接收文件后上传到Vercel Blob:
    import { put } from '@vercel/blob';
    import multer from 'multer';
    
    // 改用内存存储
    const storage = multer.memoryStorage();
    const upload = multer({ storage });
    
    // 在上传接口中处理文件
    router.post('/create-jwt-object', upload.array('images', 2), async (req, res) => {
      if (!req.files) {
        return res.status(400).send('No files uploaded');
      }
    
      const uploadedUrls = [];
      for (const file of req.files as Express.Multer.File[]) {
        const { url } = await put(file.originalname, file.buffer, {
          access: 'public',
        });
        uploadedUrls.push(url);
      }
    
      // 后续使用uploadedUrls中的地址生成Google Wallet会员卡
      res.status(200).json({ imageUrls: uploadedUrls });
    });
    

2. 修正vercel.json配置(配合云存储)

如果使用云存储,无需再配置本地uploads的路由,保持后端路由即可:

{
    "version": 2,
    "builds": [
        {"src": "src/app.ts", "use": "@vercel/node"}
    ],
    "routes": [
        {"src": "/(.*)", "dest": "src/app.ts"}
    ]
}

3. 临时测试方案(不推荐生产环境)

如果只是临时测试,可修改Multer的存储路径为Vercel允许的临时目录(/tmp),并调整Express静态服务指向该目录,但文件仍会在容器销毁后丢失:

// 修改Multer存储路径
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/uploads'); // Vercel允许的临时目录
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});

// 调整静态服务
app.use('/uploads', express.static('/tmp/uploads'));

内容的提问来源于stack exchange,提问作者Ilias Kadyrkulov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:05:23