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

MERN应用中sharp中间件内req未定义,后续控制器正常的问题求助

问题分析与解决方案

核心问题梳理

你遇到的异常来自三个关键问题:

  • 路由中的拼写错误
  • 中间件顺序颠倒
  • Multer存储配置与图片处理逻辑不兼容

1. 修复路由拼写错误

你的/new路由里把convertToWebP误写为converToWebP,导致中间件未被正确加载,直接引发req相关异常:

// 错误写法
router.post("/new", isLoggedIn, converToWebP, upload.array("images"), createCountry);

// 正确写法
router.post("/new", isLoggedIn, upload.array("images"), convertToWebP, createCountry);

2. 调整中间件顺序

convertToWebP依赖Multer解析后的req.files,必须把upload.array("images")放在convertToWebP之前,否则中间件里根本拿不到文件数据。

3. 修改Multer存储配置

你当前使用Cloudinary直接存储,这种模式下Multer会直接把文件上传到Cloudinary,不会在req.files中保留buffer,导致Sharp无法读取文件内容。需要改成内存存储,先把文件存在内存中处理,再上传到Cloudinary:

// 替换原有upload配置
const storage = multer.memoryStorage(); // 用内存存储替代Cloudinary直接存储
const upload = multer({ storage: storage });

4. 重写convertToWebP中间件

文件存在内存buffer后,转成WebP格式再手动上传到Cloudinary,最后构造符合控制器预期的文件对象:

const sharp = require("sharp");
const { cloudinary } = require("../imageupload/cloudinary");

exports.convertToWebP = async (req, res, next) => {
  try {
    req.files = await Promise.all(req.files.map(async (file) => {
      // 将文件转换为WebP格式
      const webpBuffer = await sharp(file.buffer)
        .toFormat('webp')
        .toBuffer();

      // 上传处理后的WebP到Cloudinary
      const uploadResult = await new Promise((resolve, reject) => {
        cloudinary.uploader.upload_stream(
          { resource_type: "image", format: "webp" },
          (error, result) => {
            if (error) reject(error);
            resolve(result);
          }
        ).end(webpBuffer);
      });

      // 返回控制器需要的文件结构
      return {
        path: uploadResult.secure_url,
        filename: uploadResult.public_id,
        originalname: `${file.originalname}.webp`
      };
    }));
    next();
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
};

5. 确保Body解析中间件已加载

在Express主文件中,必须在挂载路由前加载Body解析中间件,否则req.body会为空:

const express = require("express");
const app = express();

// 必须放在路由挂载之前
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 挂载路由
app.use("/countries", require("./routes/country"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:40:33