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

Firebase Cloud Function解析FormData报500错误求助

排查Firebase Cloud Function中Busboy解析FormData的500错误

问题根源分析

你的后端代码存在多处逻辑错误,直接导致了500服务器错误,核心问题如下:

  1. 提前终止请求
    在Busboy还未完成文件解析、GCS上传等核心操作时,你就调用了res.status(200).json({message: "Method Works"});,直接结束了HTTP请求,后续异步逻辑被迫中断,触发服务器异常。

  2. Promise链式调用误用
    busboy.on("finish", () => {...})返回的是EventEmitter对象,并非Promise,因此后续的.then()和.catch()完全无效——GCS上传的错误无法被捕获,上传完成后的响应也无法正确发送。

  3. 重复发送响应
    在Busboy的file事件回调中直接发送res.status(200).json({imageDetails: uploadData});,违反了HTTP单请求单响应的规范,导致服务器报错。

  4. 边界情况未处理
    若前端未上传文件,uploadData会保持null,此时调用bucket.upload(uploadData.file)会直接抛出未捕获的错误。


修正后的后端代码

const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const app = express();
const Busboy = require("busboy");
const os = require("os");
const path = require("path");
const fs = require("fs");

const gcconfig = {
  projectId: "athelasapp",
  keyFilename: "athelasapp-firebase-adminsdk-yojnp-1e9141a009.json",
};

const { Storage } = require("@google-cloud/storage");
const gcs = new Storage(gcconfig);
app.use(cors({ origin: "http://localhost:3000" }));

exports.uploadFile = functions.https.onRequest(app);

app.post("/", (req, res) => {
  if (req.method !== "POST") {
    return res.status(405).json({
      message: "Method Not Allowed",
    });
  }

  const busboy = new Busboy({ headers: req.headers });
  let uploadData = null;

  busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
    const filepath = path.join(os.tmpdir(), filename);
    uploadData = { file: filepath, type: mimetype };
    // 添加文件写入错误监听
    const writeStream = fs.createWriteStream(filepath);
    writeStream.on("error", (err) => {
      console.error("临时文件写入失败:", err);
      return res.status(500).json({ message: "文件写入临时目录失败" });
    });
    file.pipe(writeStream);
  });

  busboy.on("finish", async () => {
    try {
      if (!uploadData) {
        return res.status(400).json({ message: "未上传任何文件" });
      }

      const bucket = gcs.bucket("athelasapp.appspot.com");
      await bucket.upload(uploadData.file, {
        uploadType: "media",
        metadata: {
          metadata: {
            contentType: uploadData.type,
          },
        },
      });

      res.status(200).json({
        message: "文件上传成功",
        imageDetails: uploadData,
      });
    } catch (err) {
      console.error("GCS上传错误:", err);
      res.status(500).json({
        message: "文件上传失败",
        error: err.message,
      });
    }
  });

  busboy.end(req.rawBody);
});

前端额外优化建议

添加错误捕获逻辑,便于排查前端侧问题:

axios.post('https://us-central1-athelasapp.cloudfunctions.net/uploadFile', fd)
.then(res => {
  console.log("上传成功:", res)
})
.catch(err => {
  console.error("上传失败:", err.response?.data || err.message);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:54:21