Node.js 从文件上载节点访问原始文件流
我正在创建一个应用程序,它需要上传一些文件并直接发送到S3。我甚至不希望在我的服务器上有tmp文件,所以我使用的是Knox模块,我希望从Fornighous获取原始流,并通过Knox将其发送到S3。我使用Knox做了类似的事情,使用以下代码下载了一个文件:Node.js 从文件上载节点访问原始文件流,node.js,file-upload,amazon-s3,Node.js,File Upload,Amazon S3,我正在创建一个应用程序,它需要上传一些文件并直接发送到S3。我甚至不希望在我的服务器上有tmp文件,所以我使用的是Knox模块,我希望从Fornighous获取原始流,并通过Knox将其发送到S3。我使用Knox做了类似的事情,使用以下代码下载了一个文件: knox.downloads.get(widget.download).on('response',function(sres){ res.writeHead(200, { 'Content-Type':'applic
knox.downloads.get(widget.download).on('response',function(sres){
res.writeHead(200, {
'Content-Type':'application/zip',
'Content-Length': sres.headers['content-length'],
'Content-Disposition':'attachment; filename=' + widget.download
});
util.pump(sres, res);
}).end();
现在我想在oposite方向做一些类似的事情(从浏览器上传文件到S3)
到目前为止,我已经编写了一个事件处理程序,用于在上传文件时捕获文件中的每一条数据:
var form = new formidable.IncomingForm();
form.onPart = function(part){
if(!part.filename){
form.handlePart(part);
}else{
if(part.name == 'download'){
// Upload to download bucket
controller.putDownload(part);
}else{
// Upload to the image bucket
controller.putImage(part);
}
//res.send(sys.inspect(part));
}
}
form.parse(req, function(err, fields, files){
if(err){
res.json(err);
}else{
res.send(sys.inspect({fields:fields, files:files}), {'content-type':'text/plain'});
//controller.createWidget(res,fields,files);
}
});
controller.putDownload = function(part){
part.addListener('data', function(buffer){
knox.download.putStream(data,part.filename, function(err,s3res){
if(err)throwError(err);
else{
console.log(s3res);
}
});
})
knox.downloads.putStream(part, part.filename, function(err,s3res){
if(err)throwError(err);
else{
console.log(s3res);
}
});
}
但是数据事件只给了我缓冲区。那么有可能捕获流本身并将其推送到S3吗?您没有办法捕获流,因为数据必须由用户进行转换。您得到的
缓冲区是以缓冲区.长度为单位的文件内容:这可能是一个问题,因为查看Fornighed的文档,似乎在文件完全上传之前,它无法可靠地报告文件大小,而Knox的put
方法可能需要这样做
以前从未以这种方式使用过Knox,但您可能会有这样的运气:
controller.putDownload = function(part){
var req = knox.download.put(part.filename, {
'Content-Type': 'text/plain'
});
part.addListener('data', function(buffer){
req.write(buffer);
});
req.on('response', function(res){
// error checking
});
req.end();
}
有点不确定的反应检查位,但…看看你是否可以鞭策到形状。另外,还有一个可能对您有用的writeup。您要做的是重写表单。onPart
方法:
IncomingForm.prototype.onPart = function(part) {
// this method can be overwritten by the user
this.handlePart(part);
};
Professional的默认行为是将部件写入文件。你不会想要的。您希望处理要写入knox下载的“part”事件。从这个开始:
form.onPart = function(part) {
if (!part.filename) {
// let formidable handle all non-file parts
form.handlePart(part);
return;
}
然后打开knox请求并自行处理原始零件事件:
part.on('data', function(data) {
req.write(data);
});
part.on('end', function() {
req.end();
});
part.on('error', function(err) {
// handle this too
});
另外,如果请求写入(数据)
返回false,则表示发送缓冲区已满。您应该暂停这个强大的解析器。当您从Knox流中获得排放
事件时,您应该继续 改用。它支持您想要的这种流媒体。它甚至有一个直接流式传输到s3的例子:在一个Express中间件中,我使用强大的
和直通
将文件流式上传到s3(在我的例子中,是通过Minio SDK兼容s3的Minio;我相信它也适用于使用相同Minio SDK的AWS s3)
下面是示例代码
const formidable = require('formidable')
const { PassThrough } = require('stream')
const form = new formidable.IncomingForm()
const pass = new PassThrough()
const fileMeta = {}
form.onPart = part => {
if (!part.filename) {
form.handlePart(part)
return
}
fileMeta.name = part.filename
fileMeta.type = part.mime
part.on('data', function (buffer) {
pass.write(buffer)
})
part.on('end', function () {
pass.end()
})
}
form.parse(req, err => {
if (err) {
req.minio = { error: err }
next()
} else {
handlePostStream(req, next, fileMeta, pass)
}
})
和handlePostStream
如下所示,供您参考:
const uuidv1 = require('uuid/v1')
const handlePostStream = async (req, next, fileMeta, fileStream) => {
let filename = uuidv1()
try {
const metaData = {
'content-type': fileMeta.type,
'file-name': Buffer.from(fileMeta.name).toString('base64')
}
const minioClient = /* Get Minio Client*/
await minioClient.putObject(MINIO_BUCKET, filename, fileStream, metaData)
req.minio = { post: { filename: `${filename}` } }
} catch (error) {
req.minio = { error }
}
next()
}
你也可以找到。我被卡住了,改用多方参与解决了这个问题