node.js - 使用 NodeJS 和 Busboy 在 Firebase 上上传多个图像
问题描述
我创建了使用 NodeJS 和 Busboy 在 Firebase 上上传单个图像的函数,该函数返回图像 url。允许的图片扩展名只有.jpg
和.png
。它将生成随机文件名并使用storageBucket
.
但是,我正在努力重构这个功能,所以我可以上传多张图片。我尝试了几次尝试,但没有运气。如果所有图像都成功上传,它应该返回图像 url 数组。
这是我的单张图片上传功能:
const { admin, db } = require("./admin");
const config = require("./config");
exports.uploadImage = (req, res, url, folder) => {
const BusBoy = require("busboy");
const path = require("path");
const os = require("os");
const fs = require("fs");
const busboy = new BusBoy({ headers: req.headers });
let imageFileName;
let imageToBeUploaded = {};
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
if (mimetype !== "image/jpeg" && mimetype !== "image/png") {
return res
.status(400)
.json({ error: "Wrong file type submitted!" });
}
// Getting extension of any image
const imageExtension = filename.split(".")[
filename.split(".").length - 1
];
// Setting filename
imageFileName = `${Math.round(
Math.random() * 1000000000
)}.${imageExtension}`;
// Creating path
const filepath = path.join(os.tmpdir(), imageFileName);
imageToBeUploaded = { filepath, mimetype };
file.pipe(fs.createWriteStream(filepath));
});
busboy.on("finish", () => {
admin
.storage()
.bucket()
.upload(imageToBeUploaded.filepath, {
destination: `${folder}/${imageFileName}`,
resumable: false,
metadata: {
metadata: {
contentType: imageToBeUploaded.mimetype
}
}
})
.then(() => {
const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o${folder}%2F${imageFileName}?alt=media`;
if (url === `/users/${req.user.alias}`) {
return db.doc(`${url}`).update({ imageUrl });
} else {
return res.json({ imageUrl });
}
})
.then(() => {
return res.json({
message: "Image uploaded successfully!"
});
})
.catch(err => {
console.log(err);
return res.status(500).json({ error: err.code });
});
});
busboy.end(req.rawBody);
};
任何建议如何继续?
解决方案
你的代码几乎完成了,你所要做的就是创建一个 promise 数组并等待所有的解决。
let imageFileName = {}
let imagesToUpload = []
let imageToAdd = {}
//This triggers for each file type that comes in the form data
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
if (mimetype !== "image/jpeg" && mimetype !== "image/png") {
return res
.status(400)
.json({ error: "Wrong file type submitted!" });
}
// Getting extension of any image
const imageExtension = filename.split(".")[
filename.split(".").length - 1
];
// Setting filename
imageFileName = `${Math.round(
Math.random() * 1000000000
)}.${imageExtension}`;
// Creating path
const filepath = path.join(os.tmpdir(), imageFileName);
imageToAdd = {
imageFileName
filepath,
mimetype };
file.pipe(fs.createWriteStream(filepath));
//Add the image to the array
imagesToUpload.push(imageToAdd);
});
busboy.on("finish", () => {
let promises = []
let imageUrls = []
imagesToUpload.forEach(imageToBeUploaded => {
imageUrls.push(`https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o${folder}%2F${imageFileName}?alt=media`)
promises.push(admin
.storage()
.bucket()
.upload(imageToBeUploaded.filepath, {
destination: `${folder}/${imageFileName}`,
resumable: false,
metadata: {
metadata: {
contentType: imageToBeUploaded.mimetype
}
}
}))
})
try{
await Promises.all(resolve)
res.status(200).json({msg: 'Successfully uploaded all images', imageUrls})
}catch(err){ res.status(500).json(err) }
});
busboy.end(req.rawBody);
有了它,您应该能够全部上传它们,只需将所有承诺放在一个数组中并使用该Promise.all
方法等待它们解决。我使用 async/await 实现了它,因为这就是我一直在做的事情,但我想你在使用回调时不会有问题。
代码也很乱,但主要是因为我不知道如何使用这个文本编辑器,我希望你仍然能理解它
推荐阅读
- asp.net - ASP.Net 断点设置但未在 Visual Studio 2019 中触发
- lua - 解析文本文件 - Lua
- json - 使用 lottie.js 包含 json 文件作为路径
- json - 在颤振中解析 JsonData 时出现意外错误
- stripe-payments - 如何在条带中实现 3d 安全认证?
- java - 为什么调用 reactor/core/Scannable 时会抛出 java.lang.VerifyError?
- python - 遍历多个 Pandas 列并获取频率值
- wpf - XAML StringFormat 中的# 是什么?
- python-3.x - 我怎样才能让我的请求代理再次工作(python)?
- powershell - 更新多个用户