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

Firebase云函数(TypeScript)文件上传遇form.parse阻塞问题排查

Firebase云函数文件上传超时,form.parse回调未执行

我尝试通过以下curl命令上传文件到Firebase云函数做后续处理,但执行后出现超时问题,form.parse的回调函数始终未触发,日志仅输出到进度0/4720 bytes就停止了。

上传用curl命令

curl --location 'http://127.0.0.1:5001/{PROJECT_ID}/us-central1/fileProcess' \
--form 'file=@"/Users/kishan/Downloads/C8tjkue6Ao.pdf"'

云函数代码(Node.js TypeScript)

import * as express from "express";
import * as admin from "firebase-admin";
import * as functions from "firebase-functions/v1";
import {Fields, Files, IncomingForm} from "formidable";

if (!admin.apps.length) {
  admin.initializeApp();
}

const app = express();
app.use(express.json({limit: "50mb"}));
app.use(express.urlencoded({extended: false, limit: "50mb"}));

app.post("/", (req: express.Request, res: express.Response): void => {
  console.log("[INFO] Received request:", req.method);
  console.log("[DEBUG] Request Headers:", req.headers);

  const form = new IncomingForm({
    keepExtensions: true,
    multiples: true,
    uploadDir: '/tmp' // 显式设置上传目录
  });

  // 进度跟踪
  form.on('progress', (bytesReceived, bytesExpected) => {
    console.log(`[DEBUG] Progress: ${bytesReceived}/${bytesExpected} bytes`);
  });

  // 错误处理
  form.on('error', (err) => {
    console.error('[ERROR] Form error:', err);
    res.status(500).send({message: 'Error processing form'});
  });

  // 文件接收事件
  form.on('file', (name, file) => {
    console.log('[DEBUG] Received file:', name, file.originalFilename);
  });

  try {
    form.parse(req, (err: Error | null, fields: Fields, files: Files): void => {
      console.log("[DEBUG] Inside form.parse callback.");

      if (err) {
        console.error("[ERROR] Failed to parse form:", err);
        res.status(400).send({message: "Error parsing form data"});
        return;
      }

      if (!files || !files.file) {
        console.error("[ERROR] File is required");
        res.status(400).send({message: "File is required"});
        return;
      }

      const fileData = Array.isArray(files.file) ? files.file[0] : files.file;

      if (!fileData.originalFilename) {
        console.error("[ERROR] File has no original filename");
        res.status(400).send({message: "Invalid file data"});
        return;
      }

      console.log("[INFO] Uploaded file name:", fileData.originalFilename);

      res.status(200).send({
        message: "File uploaded successfully",
        fileName: fileData.originalFilename,
      });

      console.log("[SUCCESS] File handled successfully");
    });
  } catch (error) {
    console.error("[ERROR] Exception in form parsing:", error);
    res.status(500).send({message: "Internal server error"});
  }
});

export const fileProcess = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '1GB' // 增加内存分配
  })
  .https.onRequest(app);

日志输出

[INFO] Received request: POST
[DEBUG] Request Headers: {
  'user-agent': 'PostmanRuntime/7.43.0',
  accept: '*/*',
  'postman-token': '36ff596e-6822-4f80-b628-7da73efcbea1',
  host: '127.0.0.1:5001',
  'accept-encoding': 'gzip, deflate, br',
  connection: 'keep-alive',
  'content-type': 'multipart/form-data; boundary=--------------------------430674860192243674092838',
  'content-length': '4720'
}
[DEBUG] Progress: 0/4720 bytes

问题原因

你给Express添加了express.json()和express.urlencoded()中间件,这两个中间件会提前尝试解析请求体,导致formidable无法读取原始的multipart请求流,进而卡住无法触发parse回调。

解决方法

  1. 直接移除冲突中间件:如果这个云函数只处理文件上传请求,删掉app.use(express.json(...))和app.use(express.urlencoded(...))即可,formidable需要直接处理原始请求数据。
  2. 针对路由跳过中间件:如果其他路由需要这两个中间件,给上传路由单独跳过:
    // 全局中间件,排除上传路由
    app.use((req, res, next) => {
      if (req.path === '/' && req.method === 'POST') {
        return next();
      }
      express.json({limit: "50mb"})(req, res, next);
    });
    
    app.use((req, res, next) => {
      if (req.path === '/' && req.method === 'POST') {
        return next();
      }
      express.urlencoded({extended: false, limit: "50mb"})(req, res, next);
    });
    
  3. 检查formidable版本:确保使用最新稳定版,避免版本兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:28:18