我正在考虑将data-url
存储在我的mongoDB中,而不是存储对文件的引用或使用GridFS。
数据网址:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAAEsCAYAAAB38aczAAAgAElEQV
我存储的所有文件都是JPG或PNG,大小小于1MB。
我想知道这是否被认为是不好的做法,以及读取和写入操作的性能影响,将data-url
s 1)存储在单独的集合中2)作为集合中的元数据。
我对小文件存储的任何其他建议持开放态度。
首先,我不会将base64编码数据存储在完全能够存储二进制数据的数据库中。那只是浪费空间。存储图像本身,而不是它的base64表示,即不是data : "VBORw0KGgoAAAANSUhEUgAAA..."
,而是data : BinData("VBORw0KGgoAAAANSUhEUgAAA...")
(前者是MongoDB的字符串,后者是二进制数据)。Base64 将大小增加了 33%。
除此之外,我认为这很好。权衡是 1 个请求获取所有数据与多个请求。存储较大数据块的缺点是所有数据都必须在RAM中一段时间,但在1MB时,这可能不是问题。
但是,您应该确保在不需要图像的情况下不要获取文档。 1MB 并不算太多,但对于读取量大的集合来说,这是一场灾难。
我刚刚完成了一个解决方案。此解决方案适用于 Ajax,因此您可以在 Javascript 中使用fetch
调用。奇怪的是,在整个互联网上找不到这种解决方案,这就是为什么我帮助其他想要使用数据 uris 的图像的人:-)
型号:
cmsImage: { data: Buffer, contentType: String }
存储在MongoDB中:
let rawData = fs.readFileSync(`${root}public/uploads/` + file.originalname);
let base64Data = Buffer.from(rawData).toString('base64');
// upload this image
let image = {
cmsImage: {
data: base64Data,
contentType: file.mimetype
}
};
// in this record in the database
await this.model.findByIdAndUpdate(body.id, image);
从MongoDB检索并动态创建图像元素:
// decode image from database as image uri
let imageArray = new Int8Array(image.data.data);
let decodedImage = new TextDecoder().decode(imageArray);
// image
let cmsImage = document.createElement("img");
cmsImage.src = "data:" + image.contentType + ";base64," + decodedImage;
cmsImage.alt = "image";
cmsContent.appendChild(cmsImage);
Multer - 使用原始文件上传到数据库。
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
});
this.upload = multer({ storage: storage });
上传到目录
this.upload.single(uploadImage)