流上传文件到S3上使用强大的和Node.js的(诺克斯或AWS-SDK) [英] Stream uploading file to S3 on Node.js using formidable and (knox or aws-sdk)

查看:376
本文介绍了流上传文件到S3上使用强大的和Node.js的(诺克斯或AWS-SDK)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想上载流通过的形式直接向亚马逊S3存储提交了一份文件,使用 AWS-SDK 诺克斯。表单处理完成与强大

我的问题是:我该如何正确使用使用强大的与AWS-SDK(或诺克斯),所有这些库的最新功能,用于处理流

我知道,这个话题已经被问这里的不同口味,如:

  • <一个href="http://stackoverflow.com/questions/7505871/how-to-receive-an-uploaded-file-using-node-js-formidable-library-and-save-it-to">How使用Node.js的强大的库接收上传的文件,然后使用诺克斯其保存到Amazon S3?
  • <一个href="http://stackoverflow.com/questions/12526673/node-application-stream-file-upload-directly-to-amazon-s3">node应用程序流文件直接上传到Amazon S3
  • <一个href="http://stackoverflow.com/questions/7860449/accessing-the-raw-file-stream-from-a-node-formidable-file-upload">Accessing从一个节点,强大的文件上传原始文件流(及其对overiding非常有用公认的答案form.onPart())

不过,我相信答案是有点过时和/或偏离主题(CORS支持IE,我不希望用现在因为各种原因)和/或,最重要的是,没有提及到无论从AWS-SDK最新功能(参见:<一href="https://github.com/aws/aws-sdk-js/issues/13#issuecomment-16085442">https://github.com/aws/aws-sdk-js/issues/13#issuecomment-16085442)或诺克斯(特别是putStream()或其readableStream.pipe(REQ)的变体,无论在doc )。

在挣扎几个小时,我来到了我需要一些帮助(声明:我是一个相当有流新手)的结论。

HTML表单:

 &LT;形式的行动=/ uploadPicture的方法=邮报是enctype =的multipart / form-data的&GT;
  &LT;输入名称=图片类型=文件接受=图像/ *&GT;
  &LT;输入类型=提交&GT;
&LT; /形式GT;
 

防爆preSS bodyParser中间件配置是这样的:

  app.use(如press.bodyParser({推迟:真}))
 

POST请求处理程序:

  uploadPicture =(REQ,水库,下一个) - &GT;
  表=新formidable.IncomingForm()
  form.parse(REQ)

  form.onPart =(部分) - &GT;
    如果不是part.filename
      #让强大的处理所有非文件部分(场)
      form.handlePart(部分)
    其他
      handlePart(部分,form.bytesExpected)

  handlePart =(部件,文件大小) - &GT;
    #AWS-SDK版本
    PARAMS =
      斗:mybucket
      重点:part.filename
      CONTENTLENGTH:文件大小
      主体:一部分#传流对象之身参数

    awsS3client.putObject(PARAMS,(犯错,数据) - &GT;
      如果犯错
        的console.log犯错
      其他
        的console.log数据
    )
 

不过,我收到以下错误:

  

{[应为requestTimeout:你的套接字连接到服务器无法读取或写入超时期限内。空闲连接将被关闭。]

     

消息:你的套接字连接到服务器无法读取或写入超时期限内。空闲连接将被关闭。,     code:'应为requestTimeout,     名称:应为requestTimeout,     状态code:400,     重试:假}

的handlePart()函数诺克斯版量身定制的这种方式也惨遭失败:

  handlePart =(部件,文件大小) - &GT;
  标题=
    内容长度:文件大小
    内容类型:part.mime
  knoxS3client.putStream(部分,part.filename,头,(犯错,RES) - &GT;
    如果犯错
      的console.log犯错
    其他
      的console.log水库
  )
 

我也得到一个很大的水库有400状态code某处对象。

区域被配置为欧盟 - 西-1 在这两种情况下。

其他注意事项:

  

节点0.10.12

     

最新的强大来自NPM(1.0.14)

     

最新的AWS-SDK来自NPM(1.3.1)

     

从故宫最新诺克斯(0.8.3)

解决方案

那么,根据厉害的创造者 < /一>,直接分流到Amazon S3是不可能的:

  

在S3 API要求您创建它们时提供新的文件的大小。这个信息不能用于多部分/形式的数据文件,直到它们已经被完全接收。这意味着流是不可能的。

实际上,的 form.bytesExpected 的指整个表格的大小,而不是单一的文件的大小。

中的数据,因此必须要么被上传到S3之前,先砸在服务器上的内存或磁盘。

I'm trying to stream upload a file submitted via a form directly to an Amazon S3 bucket, using aws-sdk or knox. Form handling is done with formidable.

My question is: how do I properly use formidable with aws-sdk (or knox) using each of these libraries' latest features for handling streams?

I'm aware that this topic has already been asked here in different flavors, ie:

However, I believe the answers are a bit outdated and/or off topic (ie. CORS support, which I don't wish to use for now for various reasons) and/or, most importantly, make no reference to the latest features from either aws-sdk (see: https://github.com/aws/aws-sdk-js/issues/13#issuecomment-16085442) or knox (notably putStream() or its readableStream.pipe(req) variant, both explained in the doc).

After hours of struggling, I came to the conclusion that I needed some help (disclaimer: I'm quite a newbie with streams).

HTML form:

<form action="/uploadPicture" method="post" enctype="multipart/form-data">
  <input name="picture" type="file" accept="image/*">
  <input type="submit">
</form>

Express bodyParser middleware is configured this way:

app.use(express.bodyParser({defer: true}))

POST request handler:

uploadPicture = (req, res, next) ->
  form = new formidable.IncomingForm()
  form.parse(req)

  form.onPart = (part) ->
    if not part.filename
      # Let formidable handle all non-file parts (fields)
      form.handlePart(part)
    else
      handlePart(part, form.bytesExpected)

  handlePart = (part, fileSize) ->
    # aws-sdk version
    params =
      Bucket: "mybucket"
      Key: part.filename
      ContentLength: fileSize
      Body: part # passing stream object as body parameter

    awsS3client.putObject(params, (err, data) ->
      if err
        console.log err
      else
        console.log data
    )

However, I'm getting the following error:

{ [RequestTimeout: Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.]

message: 'Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.', code: 'RequestTimeout', name: 'RequestTimeout', statusCode: 400, retryable: false }

A knox version of handlePart() function tailored this way also miserably fails:

handlePart = (part, fileSize) ->
  headers =
    "Content-Length": fileSize
    "Content-Type": part.mime
  knoxS3client.putStream(part, part.filename, headers, (err, res) ->
    if err
      console.log err
    else
      console.log res
  )      

I also get a big res object with a 400 statusCode somewhere.

Region is configured to eu-west-1 in both case.

Additional notes:

node 0.10.12

latest formidable from npm (1.0.14)

latest aws-sdk from npm (1.3.1)

latest knox from npm (0.8.3)

解决方案

Well, according to the creator of Formidable, direct streaming to Amazon S3 is impossible :

The S3 API requires you to provide the size of new files when creating them. This information is not available for multipart/form-data files until they have been fully received. This means streaming is impossible.

Indeed, form.bytesExpected refers to the size of the whole form, and not the size of the single file.

The data must therefore either hit the memory or the disk on the server first before being uploaded to S3.

这篇关于流上传文件到S3上使用强大的和Node.js的(诺克斯或AWS-SDK)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆