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

线上环境Axios+Multer上传FormData报Unexpected end of form错误

线上环境Multer处理FormData POST请求时出现Unexpected end of form at .callFinal错误

本地环境使用Axios发送带FormData的POST请求、Multer处理multipart/form-data正常,但线上环境持续触发Unexpected end of form at .callFinal错误。请求的Content-Type已正确设置为带边界的multipart/form-data,参考相关方案后问题仍未解决(暂未尝试降级Multer)。当前使用Multer版本为1.4.5-lts.1。

已尝试的解决方法

  • 手动设置请求头(未设置时Axios也会自动生成正确的multipart/form-data头)
  • 在Multer中间件前添加bodyParser.json({extended:true})
  • 移除全局的bodyParser.json()
  • 替换文件上传中间件为express-fileupload
  • 调整FormData项顺序,将文件字段放在最后
  • 使用不同HTTP客户端发送请求

相关代码片段

前端API调用代码

export const uploadFiles = async ({
    formData: FormData;
    groupId:string
) => {
    try {
        const res = await axios({
            method: "post",
            url: `${EnvironmentUtils.getBaseUrl()}/files/upload`,
            params: {
                groupId,
            },
            data: formData,
            headers: {
                ApiKey: EnvironmentUtils.getApiKey(),
            },
            withCredentials: true,
    } catch (err) {
        const publicErrMsg = err?.response?.data?.message;
        throw new Error(
            `Error when uploading file: ${publicErrMsg || err.message}`,
        );
    }
};

FormData组装代码

const upload = useCallback(
        async (files: FileList) => {
            const formData = new FormData();
            formData.append("filesData", files[0]);
            formData.append("folderPath", btoa(selectedFolderPath || ""));
            formData.append("friendlyName", files[0].name);
            try {
                const res = await uploadFiles(
                    formData,
                    groupId
                );

后端Multer中间件配置

export const upload = Multer({
    storage: Multer.memoryStorage(),
    limits: {
        fileSize:
            FirebaseUtils.getEnvironmentVar("multer.max.file_size") ||
            10 * 1024 * 1024, // 最大10MB
        fieldSize:
            FirebaseUtils.getEnvironmentVar("multer.max.field_size") ||
            10 * 1024 * 1024, // 最大10MB
    },
});

路由配置

app.post(
    "/files/upload",
    authManager,
    MulterMiddleware.upload.single("filesData"),
    Controller.handlePostFileUploads,
);

请求处理函数

export const handlePostFileUploads: RequestHandler = async (req, res) => {
    const groupId = req.groupId!;

    const file = req.file;
    const { folderPath, friendlyName } = req.body; // 这会不会是问题所在?

Server.js基础配置

const express = require("express")();
express.use(bodyParser.json());

可能的原因分析

  1. 全局中间件冲突:虽然尝试过移除全局bodyParser.json(),但线上环境可能未生效,或者存在其他提前解析请求体的中间件。Multer需要直接读取原始的multipart/form-data请求体,如果被bodyParser等中间件先解析,会导致请求体被截断,触发表单解析不完整错误。
  2. 线上代理/网关限制:比如Nginx等反向代理的client_max_body_size设置过小,或者对multipart请求的边界处理异常,导致请求体在传输过程中被截断。
  3. 版本兼容性问题:线上环境的Node.js版本与本地不一致,当前使用的Multer LTS版本可能与线上Node版本存在兼容性问题,导致表单解析逻辑出错。
  4. 参数传递方式影响:将groupId放在URL参数中传递,线上代理可能对URL参数的处理逻辑干扰了请求体的解析,可以尝试将groupId放入FormData中传递,排除此变量的影响。
  5. 表单字段编码异常:folderPath使用btoa进行Base64编码,线上环境可能存在编码/解码的差异,或者代理自动转义了特殊字符,导致单个字段解析失败,进而中断整个表单的解析流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:54:57