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

Node.js上传Google Cloud Storage无报错但所有文件均为0字节问题

问题根因与解决方案

你遇到的Google Cloud Storage上传后文件为0字节的问题,90%以上的情况来源于上游文件解析中间件配置错误、写入流逻辑异常两类原因,对应修复方案如下:

1. 修复文件上传中间件配置

你代码中依赖req.file.buffer写入文件内容,如果你用的是常用的multer中间件处理上传,必须显式配置内存存储模式,默认的磁盘存储模式不会填充req.file.buffer字段,只会写入本地磁盘路径,此时你传入的是空值,自然会生成0字节文件。
正确的multer配置参考:

const multer = require('multer');
// 启用内存存储,才会生成req.file.buffer
const uploadMid = multer({
  storage: multer.memoryStorage(),
  // 可按需添加文件大小限制
  limits: { fileSize: 10 * 1024 * 1024 }
})
// 路由注册时绑定中间件,单文件上传字段名需和前端传的字段名一致
app.post('/upload', uploadMid.single('file'), upload)

2. 补全代码校验与流逻辑优化

2.1 校验buffer是否为空

在调用GCS写入流之前先校验buffer长度,提前定位上游问题:

if (req.file.buffer.length === 0) {
  return res.status(400).send('文件内容为空,请检查上传配置')
}

2.2 修复未定义变量错误

你当前代码中blobStream.on('error', err => { next(err); });用到了next但未在upload函数入参中声明,会触发未定义错误导致流中断,可补充next入参或者直接抛出错误到外层catch处理。

2.3 异步流等待

当前upload是async函数,但内部的流操作为异步回调模式,没有等待完成就可能提前返回,建议封装为Promise确保写入完成后再返回响应,优化后完整代码参考:

const gc = new Storage({
    keyFilename: path.join(__dirname, "../faslearn-ba6c817cfcea.json"),
    projectId: "faslearn"
});
const bucket = gc.bucket('faslearn_files')

const upload = async (req, res, next) => {
    try {
        if (!req.file) {
            res.status(400).send('No file uploaded.');
            return;
        }
        // 校验文件内容非空
        if (req.file.buffer.length === 0) {
            return res.status(400).send('上传文件内容为空');
        }

        const blob = bucket.file(req.file.originalname);
        const blobStream = blob.createWriteStream({ resumable: false, gzip: true });

        // 等待流写入完成
        await new Promise((resolve, reject) => {
            blobStream.on('error', reject);
            blobStream.on('finish', resolve);
            blobStream.end(req.file.buffer);
        });

        const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        res.status(200).send(publicUrl);
    } catch (err) {
        console.log("上传失败:", err);
        res.status(500).send({
            message: `Could not upload the file: ${req.file.originalname}. ${err}`,
        });
    }
};

3. 可选排查项

如果上述修改后仍有问题,可先暂时关闭createWriteStream的gzip: true配置,排查是否为gzip压缩异常导致的内容丢失,确认基础上传功能正常后再按需开启压缩。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:06:04