我正在尝试使用带有 busboy 的 express 在 Node.js 4.x 中实现文件上传。我已经能够上传文件并将它们存储在 Azure Blob 存储中。
不,我想在将文件存储到 Azure 之前验证文件类型,并拒绝任何无效的文件。
我想使用幻数进行验证。我发现
const fileType = require('file-type');
它决定了我的文件类型。
现在我试图让这项工作尽可能高效,但这是我苦苦挣扎的地方:我想直接将文件流通过管道传输到 azure。但在此之前,我需要将流中的前 5 个字节读取到由文件类型处理的缓冲区中。
从流中读取然后通过管道传输到 azure 肯定是行不通的。经过一些研究,我通过在 2 个 PassThrough 流中传输文件找到了解决方案。但现在我正在努力正确处理这两个流。
const fileType = require('file-type');
const pass = require('stream').PassThrough;
//...
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
var b = new pass;
var c = new pass;
file.pipe(b);
file.pipe(c);
var type = null;
b.on('readable', function() {
b.pause();
if(type === null) {
var chunk = b.read(5);
type = fileType(chunk) || false;
b.end();
}
});
b.on('finish', function() {
if(type && ['jpg', 'png', 'gif'].indexOf(type.ext) !== -1) {
var blobStream = blobSvc.createWriteStreamToBlockBlob(storageName,
blobName,
function (error) {
if (error) console.log('blob upload error', error);
else console.log('blob upload complete')
});
c.pipe(blobStream);
}
else {
console.error("Rejected file of type " + type);
}
});
});
此解决方案有时有效 - 有时会出现一些“结束后写入”错误。另外,我认为流没有正确关闭,因为通常,在请求之后,快递会在控制台上记录如下内容:
POST /path - - ms - -
但是这个日志消息现在在“blob 上传完成”之后的 30 到 60 秒出现,可能是由于一些超时。
知道如何解决这个问题吗?