javascript - 通过express服务器流式文件上传到s3

标签 javascript node.js express amazon-s3

我有一个快速端点,目前我在其中处理文件上传。大文件占用大量内存,因为我使用 bodyParser,它在调用我的处理函数之前将整个文件缓冲在内存中。

我从此端点中删除了 bodyParser 中间件,并且我正在努力正确使用流来基本上传输文件上传 -> Express -> s3。

这是关于 s3 方法的文档,它接受缓冲区或流。

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

路线

router.put('/files/:filename', putHandler({ s3Client: s3Client }))

我尝试过将文件流式传输到我的处理程序方法,但它似乎没有将其流式传输到 s3.upload 方法(确实不足为奇)

function put ({ s3Client }) {
  return (req, res) => {
        ...
        let whenFileUploaded = new Promise((resolve, reject) => {
          // const { Readable } = require('stream')
          // const inStream = new Readable({
            // read() {}
          // })

          let data = ''
          req.on('data', function (chunk) {
            req.log.debug('in chunk')
            data += chunk
            // inStream.push(chunk)
          })
          req.on('end', function () {
            req.log.debug('in end')
          })

          s3Client.upload(
            {
              Key: filepath,
              Body: data,
              SSECustomerAlgorithm: 'AES256',
              SSECustomerKey: sseKey.id.split('-').join('')
            },
            {
              partSize: 16 * 1024 * 1024, // 16mb
              queuSize: 1
            },
            (err, data) => err ? reject(err) : resolve(data)
          )
        })

我的猜测是,我需要创建一个流并将 req.on('data...) 传输到我的流,然后设置 Body: inStream 您可以看到我尝试了注释掉的东西,但这似乎也不起作用。

帮忙?

最佳答案

事实证明答案其实很简单。我所要做的就是传递 req 对象。

function put ({ s3Client }) {
  return (req, res) => {
        ...
        let whenFileUploaded = new Promise((resolve, reject) => {
          s3Client.upload(
            {
              Key: filepath,
              Body: req, // <-- NOTE THIS LINE
              SSECustomerAlgorithm: 'AES256',
              SSECustomerKey: sseKey.id.split('-').join('')
            },
            {
              partSize: 16 * 1024 * 1024, // 16mb
              queuSize: 1
            },
            (err, data) => err ? reject(err) : resolve(data)
          )
        })

我发现这一点的方式是 b/c 我查看了 req 对象的快速源代码,我发现它是一个 http.IncomingMessage对象-https://github.com/expressjs/express/blob/master/lib/request.js#L31

然后我查看了 Node 文档,发现 http.IncomingMessage 实现了 Readable Stream 接口(interface)

It implements the Readable Stream interface, as well as the following additional events, methods, and properties.

https://nodejs.org/docs/latest-v9.x/api/http.html#http_class_http_incomingmessage

关于javascript - 通过express服务器流式文件上传到s3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54976097/

相关文章:

javascript - jQuery attr().更改图像 block 的源和扩展名

node.js - Mongoose 直接填充创建子文档

javascript - 评估 html 正文中的 javascript 文本

node.js - 如何让express.static中间件忽略get参数?

javascript - 添加更多路由后,express.js 在每个页面上都会出现错误 500

javascript - 'next' 中的 'middleware function' 参数在 Node.js 的 Express 中如何工作?

javascript - 按 Angular js智能表中的多个 bool 属性过滤

javascript - 在 Angular Gauge Highchart 中显示类别并删除数字

javascript - 更新 url 中的查询字符串

arrays - Node.JS 将可能带有连字符的大写字符串拆分为数组