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

关于Formidable文件类型校验代码位置及提前终止非图片文件上传的技术咨询

Answers to Your Formidable Upload Questions

Problem 1: Correct Placement for Formidable File Type Validation Code

The issue here is how you're passing the filter option to Formidable. You wrapped it in a separate options object and added that as a nested property inside the Formidable config—Formidable doesn't recognize that nested options key, so your filter never runs.

Here are two straightforward fixes:

Option 1: Inline the filter directly in the main config

app.post("/api/upload", async (req, res, next) => {
  const form = formidable({
    multiples: true,
    uploadDir: "./uploads",
    maxFileSize: 1024 * 1024,
    // Place the filter directly in the top-level configuration
    filter: function ({ name, originalFilename, mimetype }) {
      // Only keep image files
      return mimetype && mimetype.includes("image");
    },
  });

  // Don't forget to parse the request to trigger the upload flow
  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    // Handle successful upload response here
    res.json({ success: true, files });
  });
});

Option 2: Merge your filter options with the main config

If you prefer to keep the filter in a separate object, use the spread operator (...) to merge its properties into the Formidable config:

app.post("/api/upload", async (req, res, next) => {
  const filterOptions = {
    filter: function ({ name, originalFilename, mimetype }) {
      return mimetype && mimetype.includes("image");
    },
  };

  const form = formidable({
    multiples: true,
    uploadDir: "./uploads",
    maxFileSize: 1024 * 1024,
    ...filterOptions, // Merge the filter into the main config
  });

  // Rest of your parse and upload handling logic...
});

Problem 2: Stop Non-Image Files Before They Upload

Your current file.destroy() approach works after the file has already been saved to disk—which is why you see files being uploaded first then deleted. The proper fix is to use the filter function from Problem 1: it runs before Formidable starts writing the file to your server, so non-image files are rejected immediately without ever touching your disk.

Here's a complete, improved example:

const fs = require("fs").promises; // Use promise-based fs for cleaner async code
const path = require("path");
const formidable = require("formidable");

app.post("/api/upload", async (req, res, next) => {
  const form = formidable({
    multiples: true,
    uploadDir: "./uploads",
    filter: ({ name, originalFilename, mimetype }) => {
      // Reject non-image files before any upload begins
      return mimetype && mimetype.includes("image");
    },
  });

  // Handle valid image files only
  form.on("file", async (field, file) => {
    // Generate a unique filename to avoid overwrites (fixed your original index issue)
    const fileExtension = path.extname(file.originalFilename);
    const uniqueFileName = `avatar-${Date.now()}-${Math.random().toString(36).slice(2)}${fileExtension}`;
    const newFilePath = path.join(form.uploadDir, uniqueFileName);

    try {
      await fs.rename(file.filepath, newFilePath);
      console.log(`Successfully processed: ${file.originalFilename}`);
    } catch (renameErr) {
      console.error("Failed to rename file:", renameErr);
      next(renameErr);
    }
  });

  // Handle rejected files or other upload errors
  form.on("error", (err) => {
    if (err.message.includes("File rejected by filter")) {
      console.log("Rejected a non-image file upload attempt");
      res.status(400).send("Error: Only image files are allowed");
    } else {
      console.error("Upload error:", err);
      next(err);
    }
  });

  // Parse the request to initiate the upload process
  form.parse(req, (parseErr, fields, files) => {
    if (parseErr) {
      next(parseErr);
      return;
    }
    res.status(200).json({ success: true, files: Object.values(files) });
  });
});

Quick note: Your original uploadDirIndex logic could cause duplicate filenames if multiple uploads happen simultaneously. The example above uses Date.now() plus a random string to ensure unique file names every time.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:07:34