【问题标题】:Stream node requests to the cloud with file metadata使用文件元数据将节点请求流式传输到云
【发布时间】:2018-12-16 12:59:22
【问题描述】:

我正在使用 koa 来构建一个 Web 应用程序,并且我希望允许用户将文件上传到它。文件需要流式传输到云端,但我想避免将文件保存在本地。

问题是在将上传流传输到可写流之前,我需要一些文件元数据。我想要 mime 类型,并可选择附加其他数据,如原始文件名等。

我尝试发送将请求的“content-type”标头设置为文件类型的二进制数据,但我希望请求具有内容类型application/octet-stream,以便我可以在后端知道如何处理请求。

我在某处读到,更好的选择是使用multipart/form-data,但我不确定如何构造请求,以及如何解析元数据以便在通过管道传输到其写入流之前通知云。

这是我当前使用的代码。基本上,它只是按原样管道请求,我使用请求标头来了解文件的类型:

module.exports = async ctx => {
  // Generate a random id that will be part of the filename.
  const id = pushid();
  // Get the content type from the header.
  const contentType = ctx.header['content-type'];
  // Get the extension for the file from the content type
  const ext = contentType.split('/').pop();

  // This is the configuration for the upload stream to the cloud.
  const uploadConfig = {
    // I must specify a content type, or know the file extension.
    contentType

    // there is some other stuff here but its not relevant.
  };

  // Create a upload stream for the cloud storage.
  const uploadStream = bucket
    .file(`assets/${id}/original.${ext}`)
    .createWriteStream(uploadConfig);

  // Here is what took me hours to get to work... dev life is hard
  ctx.req.pipe(uploadStream);

  // return a promise so Koa doesn't shut down the request before its finished uploading.
  return new Promise((resolve, reject) =>
    uploadStream.on('finish', resolve).on('error', reject)
  );
};

请假设我对上传协议和流管理了解不多。

【问题讨论】:

    标签: node.js express stream koa2 node-streams


    【解决方案1】:

    好的,经过大量搜索后,我发现有一个解析器可以处理名为busboy 的流。它非常易于使用,但在进入代码之前,我强烈建议每个处理multipart/form-data 请求的人发送至read this article

    我是这样解决的:

    const Busboy = require('busboy');
    
    module.exports = async ctx => {
      // Init busboy with the headers of the "raw" request.
        const busboy = new Busboy({ headers: ctx.req.headers });
    
        busboy.on('file', (fieldname, stream, filename, encoding, contentType) => {
            const id = pushid();
            const ext = path.extname(filename);
            const uploadStream = bucket
                .file(`assets/${id}/original${ext}`)
                .createWriteStream({
                    contentType,
                    resumable: false,
                    metadata: {
                        cacheControl: 'public, max-age=3600'
                    }
                });
    
            stream.pipe(uploadStream);
        });
    
      // Pipe the request to busboy.
        ctx.req.pipe(busboy);
    
      // return a promise that resolves to whatever you want
        ctx.body = await new Promise(resolve => {
            busboy.on('finish', () => {
                resolve('done');
            });
        });
    };
    

    【讨论】:

      猜你喜欢
      • 2017-05-05
      • 1970-01-01
      • 2020-04-10
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 2017-02-22
      • 2011-06-30
      相关资源
      最近更新 更多