我的Firebase存储桶中的文件夹和子文件夹中有很多文件。 我的实时Firebase数据库中有所有这些文件的DownloadURLs列表。 我正在尝试进行批量下载,理想情况下,创建一个.ZIP文件夹供最终用户立即下载。
其他几篇文章(例如How to download entire folder from Firebase Storage?)指出,没有内置的API可以进行批量下载,例如从存储桶中下载整个文件夹。据我所知,这并没有改变。
但是,一个相关的答案(How to download entire folder from Firebase Storage?)暗示可能可以创建.ZIP文件夹,但没有详细说明。
我怎么能...
... A)在客户端使用纯JS允许最终用户收集所有DownloadURL并立即下载文件?...
...或...
... B)使用用Node.JS编写的Cloud Function来使用DownloadURLs创建一个.ZIP文件,最终用户可以将其下载为一个文件。 (我假设.ZIP文件可以作为具有自己的DownloadURL的另一个文件存储在存储桶中,并且可以像其他文件一样下载,然后在本地解压缩并提取所有原始文件。如果不是,请更正我情况)
...还是这些方法都不可行?如果不是原因,缺少什么功能?
在此先感谢您提供任何见解!
答案 0 :(得分:0)
迟到总比没有好,您可以使用JSZip,它提供了简单的API用法。
生成zip文件后,您可以使用FileSaver进行保存/下载。
这就是我(从客户端)生成一个zip文件的方式
import JSZip from "jszip";
import saveAs from "file-saver";
generateZipFile(photosToDownload) {
var jszip = new JSZip();
//Looping through to get the download url for each image
for (let i = 0; i < photosToDownload.length; i++) {
let photoName = photosToDownload[i].photo_image_name;
let photoImageURL = photosToDownload[i].generated_image_url;
let photoImageExtension = photoName.substr(photoName.length - 4);
jszip.file(
photoName + photoImageExtension, //in my case, this produces something like 'my image.jpg'
this.downloadUrlAsPromise(photoImageURL) //generates the file we need to download
);
//If we have reached the last image in the loop, then generate the zip file
if (i == photosToDownload.length - 1) {
jszip.generateAsync({ type: "blob" }).then(function(content) {
saveAs(content, "MyZipFile.zip");
});
}
}
},
downloadUrlAsPromise(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function(evt) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(new Error("Error for " + url + ": " + xhr.status));
}
}
};
xhr.send();
});
},
答案 1 :(得分:0)
这里是一个简单的 TypeScript 代码示例,使用 ESNext 语法,使用上面@Oush 提到的相同包:
import JSZip from 'jszip';
import firebase from 'firebase/app';
import { saveAs } from 'file-saver';
export const downloadFolderAsZip = async (folderPath: string) => {
const jszip = new JSZip();
const folderRef = firebase.storage().ref(folderPath);
const files = (await folderRef.listAll()).items;
const downloadUrls: Array<string> = await Promise.all(
files.map(({ name }) => folderRef.child(name).getDownloadURL())
);
const downloadedFiles = await Promise.all(downloadUrls.map(url => fetch(url).then(res => res.blob())));
downloadedFiles.forEach((file, i) => jszip.file(files[i].name, file));
const content = await jszip.generateAsync({ type: 'blob' });
saveAs(content, folderPath);
};
请注意,您必须 guide 首先,这样才能起作用。默认情况下,Cloud Storage 没有 CORS 配置(您可以使用 gsutil cors get gs://your-bucket-name.appspot.com
命令查找),因此浏览器会因为 gcs 没有返回 CORS 标头而拒绝 fetch()
调用。
进一步阅读: