使用Web前端列出Azure容器中所有Blob,支持目录级别。

3

我目前正在开发一些代码,以使用Web前端显示指定Azure容器中的所有Blob。 我期望最终输出如下:

Directory listing with Apache Mod_autoindex

我开始创建一个虚拟存储账户,并添加了一些虚拟文件,以供我进行测试。
https://alicebob.blob.core.windows.net/documents  
├── docx  
│   ├── 201801_Discussion.docx  
│   ├── 201802_Discussion.docx  
├── xlsx  
│   ├── 201801_Summary.xlsx  
│   ├── 201802_Summary.xlsx  
│   ├── 201803_Summary.xlsx  
├── 201801_Review.pdf  
├── 201802_Review.pdf  
├── 201803_Review.pdf  

为了开发文件列表功能,我正在使用来自这里的Azure Storage JavaScript客户端库,并将所有必要的代码(.html.js文件)放在Azure静态网站$web容器中,并在静态网站配置中将index.html设置为索引文档名称错误文档路径
https://alicebob.z23.web.core.windows.net/  
├── azure-storage.blob.min.js  
├── azure-storage.common.min.js  
├── index.html  

问题在于执行列出操作的函数只有listBlobsSegmentedWithPrefixlistBlobDirectoriesSegmentedWithPrefix。因此,在我的情况下,我认为直接以良好结构/树形式列出所有blob和目录可能行不通。
我的当前方法是欺骗代码继续使用listBlobDirectoriesSegmentedWithPrefix,直到没有更多目录可列出,然后继续使用listBlobsSegmentedWithPrefix进行列表。
到目前为止,我很满意我的代码可以列出所有叶级别的Blob,并且如果它不在叶级别,则可以列出所有目录。您可以在此处查看blob列表here,并随意查看我迄今为止构建的代码的“查看源” 。
我面临的唯一问题是,如果不在叶级别上,则此代码集无法列出Blobs。例如,在alicebob存储帐户上列出这些blob时会失败:
├── 201801_Review.pdf  
├── 201802_Review.pdf  
├── 201803_Review.pdf  

这是一个预期的问题,因为如果不在叶级别上运行listBlobsSegmentedWithPrefix,它将产生以下类似的输出,这不是我想要的:
├── docx/201801_Discussion.docx  
├── docx/201802_Discussion.docx  
├── xlsx/201801_Summary.xlsx  
├── xlsx/201802_Summary.xlsx  
├── xlsx/201803_Summary.xlsx  
├── 201801_Review.pdf  
├── 201802_Review.pdf  
├── 201803_Review.pdf 

有什么建议可以解决这个问题吗?实际的实现涉及大量数据,因此我认为在这种情况下简单的if-then-else不会很有效。

对于描述如此清晰的问题,我很抱歉描述得太长了 :)

2个回答

6

列出blob时有一个名为“delimiter”的选项。让我们看代码。

blobService.listBlobsSegmentedWithPrefix('documents',null,null,{delimiter:'/'},(error,result,response)=>{
    console.log(result);
    console.log(response.body.EnumerationResults.Blobs.BlobPrefix);
})

使用分隔符/,列出操作返回两部分结果。

  1. result, contains info of blobs under the root directory of container, e.g. 201801_Review.pdf, etc. in your case.
  2. BlobPrefix in response body, contains directory names of single level with delimiter.

    [ { Name: 'docx/' }, { Name: 'xlsx/' } ]
    
使用BlobPrefix作为前缀,我们可以继续列出当前子目录的内容。
    blobService.listBlobsSegmentedWithPrefix('documents','docx/',null,{delimiter:'/'},(error,result,response)=>{
        console.log(result);
        console.log(response.body.EnumerationResults.Blobs.BlobPrefix);
    }) 

基本上,点1的结果已经足够了,你不一定要使用BlobPrefix来重构您的代码。更多信息请参见列出Blob中的使用分隔符遍历Blob命名空间一节。


抱歉耽误了,是的,delimiter选项在我的情况下完美地工作,谢谢!无论如何,对于BlobPrefix选项,我已经通过使用getDir函数从URL中解析它来在我的代码中实现了它 (https://alicebob.z23.web.core.windows.net/{BlobPrefix}),以便我可以继续列出其余的子目录。 - Andi Ariffin
@AndiAriffin 您好,不用谢。您能否接受答案以供其他人参考呢? - Jerry Liu

0

您也可以使用以下的fetch请求来完成此操作,而无需使用整个存储API的开销。

  fetch("https://cvworkshop.blob.core.windows.net/telaviv-bw/?restype=container&comp=list")
    .then(response => response.text())
    .then(str => new window.DOMParser().parseFromString(str, "text/xml"))
    .then(data => console.log(data));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接