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

NextJS中Multer无法完整上传大文件(仅上传195KB)

解决文件上传被截断至195KB的问题

针对你遇到的Multer上传大文件被截断的问题,以下是几个关键排查和修复方向:

1. 修复Multer中间件的异步处理逻辑

你的代码中直接使用await upload.single('image')(req, res),但Multer中间件基于回调实现,这种写法无法正确捕获上传过程中的错误(比如真实的文件大小超限报错)。可以用util.promisify包装,确保错误能被完整捕获:

修改upload.js:

import multer from 'multer';
import path from 'path';
import { promisify } from 'util';

const upload = multer({
  storage: multer.diskStorage({
    destination: path.join(process.cwd(), 'public/uploads'),
    filename: (req, file, callback) => {
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0');
      const day = String(now.getDate()).padStart(2, '0');
      const hours = String(now.getHours()).padStart(2, '0');
      const minutes = String(now.getMinutes()).padStart(2, '0');
      const seconds = String(now.getSeconds()).padStart(2, '0');
      const newFileName = `${year}_${month}_${day}-${hours}h_${minutes}m_${seconds}s-${file.originalname}`;
      callback(null, newFileName);
    },
  }),
  limits: {
    fileSize: 100 * 1024 * 1024, // 100MB限制
  },
});

// 将Multer中间件包装为Promise形式
const uploadSingle = promisify(upload.single('image'));

export const config = {
  api: {
    bodyParser: false,
    timeout: 0,
    responseLimit: false,
  },
};

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      await uploadSingle(req, res);
      res.status(200).json({ message: 'File uploaded successfully' });
    } catch (error) {
      console.error('Upload error details:', error); // 打印详细错误信息
      if (error instanceof multer.MulterError) {
        // 针对性处理Multer错误,比如文件大小超限
        res.status(400).json({ error: `Upload error: ${error.message}` });
      } else {
        res.status(500).json({ error: 'Error uploading file' });
      }
    }
  } else {
    res.status(405).json({ error: 'Method Not Allowed' });
  }
}

修改后可以捕获到真实的上传错误,帮你定位问题根源。

2. 检查服务器/反向代理的上传限制

如果修改后仍出现截断,大概率是服务器或反向代理的全局上传限制导致:

  • 若用Nginx部署,需在nginx.conf或站点配置中添加client_max_body_size 100M;,Nginx默认的小限制会直接截断大请求。
  • 若用Vercel等平台部署,需在项目配置中调整API路由的请求大小限制(平台默认限制通常远小于100MB)。
  • 其他Node.js服务器(如Express)若有额外的body解析中间件,需确保未设置过小的限制。

3. 配置Next.js全局请求大小限制

在next.config.js中添加全局配置,覆盖默认的请求大小限制:

/** @type {import('next').NextConfig} */
const nextConfig = {
  api: {
    bodyParser: {
      sizeLimit: '100mb',
    },
  },
}

module.exports = nextConfig

即使你的API路由已设置bodyParser: false,全局配置能确保没有其他默认限制生效。

4. 前端添加前置文件大小验证

可以在前端上传前先检查文件大小,避免无效请求:

const handleSubmit = async () => {
  if (!image) {
    console.error("No file selected");
    return;
  }

  // 前置检查文件大小是否超出限制
  const maxSize = 100 * 1024 * 1024;
  if (image.size > maxSize) {
    console.error("File exceeds 100MB limit");
    return;
  }

  const formData = new FormData();
  formData.append("image", image);

  try {
    const response = await fetch("/api/upload", {
      method: "POST",
      body: formData,
    });

    if (response.ok) {
      console.log("File uploaded successfully");
    } else {
      const errorData = await response.json();
      console.error("Error uploading file:", errorData.error);
    }
  } catch (error) {
    console.error("Error uploading file:", error);
  }
};

按以上步骤排查,重点关注反向代理的上传限制和Multer的错误捕获,即可解决文件截断问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:44:56