我正在尝试通过表单直接将文件流上传到Amazon S3存储桶,使用的是aws-sdk或knox。表单处理使用的是formidable。
我的问题是:如何正确地使用formidable与aws-sdk(或knox),以使用这些库的最新特性来处理流?
我知道这个话题已经以不同的方式在这里提出过,例如:
- 如何使用node.js formidable库接收上传的文件,并使用knox将其保存到Amazon S3中?
- Node应用程序流式上传文件直接到Amazon S3
- 从node-formidable文件上传访问原始文件流(及其在重写form.onPart()方面非常有用的接受答案)
然而,我认为这些答案有点过时和/或离题(例如CORS支持,出于各种原因,我现在不想使用),或者更重要的是,没有涉及到aws-sdk(见:https://github.com/aws/aws-sdk-js/issues/13#issuecomment-16085442)或knox(特别是putStream()或其readableStream.pipe(req)变体,在文档中有解释)的最新功能。
经过数小时的奋斗,我得出结论,我需要一些帮助(免责声明:我对流相当新手)。
HTML表单:
<form action="/uploadPicture" method="post" enctype="multipart/form-data">
<input name="picture" type="file" accept="image/*">
<input type="submit">
</form>
Express bodyParser中间件的配置方式如下:
app.use(express.bodyParser({defer: true}))
POST请求处理程序:
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
)
然而,我遇到了以下错误:
{ [RequestTimeout: 您的套接字连接在超时期间内未被读取或写入。空闲连接将被关闭。]
message: '您的套接字连接在超时期间内未被读取或写入。空闲连接将被关闭。', code: 'RequestTimeout', name: 'RequestTimeout', statusCode: 400, retryable: false }
一个经过调整的handlePart()函数的knox版本也惨遭失败:
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
)
我在某个地方也得到了一个带有400状态码的大型res对象。
在两种情况下,区域都配置为eu-west-1。
附加说明:
node 0.10.12
来自npm的最新formidable(1.0.14)
来自npm的最新aws-sdk(1.3.1)
来自npm的最新knox(0.8.3)