javascript - Google Cloud Functions - 通过 HTTP 上传到 Google Cloud Storage

标签 javascript google-cloud-platform google-cloud-functions google-cloud-storage

我正在尝试使用 Google Cloud Function 处理文件上传。此函数使用 Busboy 解析多部分表单数据,然后上传到 Google Cloud Storage。

我一直收到 ERROR: { Error: ENOENT: no such file or directory, open '/tmp/xxx.png' 触发函数时出现错误。

当 storage.bucket.upload(file) 尝试打开文件路径 /tmp/xxx.png 时,错误似乎发生在 finish 回调函数中。

示例代码

const path = require('path');
const os = require('os');
const fs = require('fs');
const Busboy = require('busboy');
const Storage = require('@google-cloud/storage');
const moment = require('moment');
const _ = require('lodash');

const projectId = 'xxx';
const bucketName = 'xxx';


const storage = new Storage({
  projectId: projectId,
});

exports.uploadFile = (req, res) => {
  if (req.method === 'POST') {
    const busboy = new Busboy({
      headers: req.headers
    });
    const uploads = []
    const tmpdir = os.tmpdir();

    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
      const filepath = path.join(tmpdir, filename)
      var obj = {
        path: filepath,
        name: filename
      }
      uploads.push(obj);

      var writeStream = fs.createWriteStream(obj.path);
      file.pipe(writeStream);
    });

    busboy.on('finish', () => {
      _.forEach(uploads, function (file) {

        storage
          .bucket(bucketName)
          .upload(file.path, {
            name: moment().format('/YYYY/MM/DD/x') + '-' + file.name
          })
          .then(() => {
            console.log(`${file.name} uploaded to ${bucketName}.`);
          })
          .catch(err => {
            console.error('ERROR:', err);
          });


        fs.unlinkSync(file.path);
      })

      res.end()
    });

    busboy.end(req.rawBody);
  } else {
    res.status(405).end();
  }
}

最佳答案

用流而不是临时文件解决了这个问题。不过目前只处理一个文件。

https://gist.github.com/PatrickHeneise/8f2c72c16c4e68e829e58ade64aba553#file-gcp-function-storage-file-stream-js

function asyncBusboy(req, res) {
  return new Promise((resolve, reject) => {
    const storage = new Storage()
    const bucket = storage.bucket(process.env.BUCKET)

    const fields = []
    const busboy = Busboy({
      headers: req.headers,
      limits: {
        fileSize: 10 * 1024 * 1024
      }
    })

    busboy.on('field', (key, value) => {
      fields[key] = value
    })

    busboy.on('file', (name, file, fileInfo) => {
      const { mimeType } = fileInfo
      const destFile = bucket.file(fileName)
      const writeStream = destFile.createWriteStream({
        metadata: {
          contentType: fileInfo.mimeType,
          metadata: {
            originalFileName: fileInfo.filename
          }
        }
      })
      file.pipe(writeStream)
    })

    busboy.on('close', function () {
      return resolve({ fields })
    })

    if (req.rawBody) {
      busboy.end(req.rawBody)
    } else {
      req.pipe(busboy)
    }
  })
}

关于javascript - Google Cloud Functions - 通过 HTTP 上传到 Google Cloud Storage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49396849/

相关文章:

javascript - 手机输入栏 : automatically push to top on select

javascript - 如何解锁输入?

google-cloud-platform - 谷歌云功能是否仅在美国执行?

node.js - 如何从 Node.js 使用 GCP 运行时配置器?

javascript - 使用 testcafe 在 Javascript 中断言数组列表

收到电子邮件后触发 firebase 功能

javascript - Firebase 的云函数 : How to access an array I have just got from firebase?

python - 如何通过 Cloud Functions 调度用 Python 编写的 Dataflow 管道?

typescript - 是否可以使用节点 js 云功能访问 FieldValue?

javascript - 查找正在更改 DOM 元素的 javascript