Firebase Cloud Function解析FormData报500错误求助
排查Firebase Cloud Function中Busboy解析FormData的500错误
问题根源分析
你的后端代码存在多处逻辑错误,直接导致了500服务器错误,核心问题如下:
提前终止请求
在Busboy还未完成文件解析、GCS上传等核心操作时,你就调用了res.status(200).json({message: "Method Works"});,直接结束了HTTP请求,后续异步逻辑被迫中断,触发服务器异常。Promise链式调用误用
busboy.on("finish", () => {...})返回的是EventEmitter对象,并非Promise,因此后续的.then()和.catch()完全无效——GCS上传的错误无法被捕获,上传完成后的响应也无法正确发送。重复发送响应
在Busboy的file事件回调中直接发送res.status(200).json({imageDetails: uploadData});,违反了HTTP单请求单响应的规范,导致服务器报错。边界情况未处理
若前端未上传文件,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
相关产品推荐
相关产品推荐

