You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Azure SAS URL从Blob存储批量下载文件至浏览器的方案咨询

Azure Blob Storage 批量下载与SAS问题解决方案

1. 直接通过SAS URL批量下载Blob为文件夹

Azure Blob Storage 不支持直接通过SAS URL让浏览器自动将整个容器/虚拟目录下的Blob打包成文件夹(ZIP)下载。如果生成的是容器级SAS URL,浏览器访问后只会列出所有Blob文件,用户需要逐个点击下载。

2. 预先打包ZIP的下载方案

如果你已经将大文件打包成ZIP存储为单个Blob,只需生成该ZIP Blob的读权限SAS URL,用户点击后即可直接下载整个ZIP文件,无需逐个下载。确保生成SAS时勾选读(r)权限,并设置合理的有效期。

3. SAS URL无法下载的排查要点

  • 权限检查:生成SAS时必须包含r(读)权限,容器级SAS还需确保包含list权限(如果需要浏览文件)。
  • 有效期检查:确认当前时间在SAS的开始时间和结束时间范围内,避免SAS已过期。
  • 访问层级检查:若容器为私有,必须使用有效的SAS;若为匿名访问,需确保Blob允许匿名读取。
  • URL格式检查:确保SAS参数正确拼接在Blob/容器URL后,无多余字符或格式错误。

4. C#代码实现方案

4.1 生成单个ZIP Blob的SAS URL

用于让用户直接下载预先打包好的ZIP文件:

using Azure.Storage.Blobs;
using Azure.Storage.Sas;

public string GenerateZipBlobSasUrl(string connectionString, string containerName, string zipBlobName)
{
    var blobServiceClient = new BlobServiceClient(connectionString);
    var containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    var blobClient = containerClient.GetBlobClient(zipBlobName);

    var sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = containerName,
        BlobName = zipBlobName,
        Resource = "b", // 指定为单个Blob
        ExpiresOn = DateTimeOffset.UtcNow.AddHours(1) // 设置1小时有效期
    };
    sasBuilder.SetPermissions(BlobSasPermissions.Read); // 添加读权限

    Uri sasUri = blobClient.GenerateSasUri(sasBuilder);
    return sasUri.ToString();
}

4.2 动态打包Blob为ZIP并返回浏览器

适合未预先打包,需要实时将指定目录/容器下的Blob打包成ZIP供用户下载(以ASP.NET Core为例):

using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System.IO.Compression;
using Microsoft.AspNetCore.Mvc;

public async Task<IActionResult> DownloadBlobsAsZip(string connectionString, string containerName, string virtualDir = null)
{
    var blobServiceClient = new BlobServiceClient(connectionString);
    var containerClient = blobServiceClient.GetBlobContainerClient(containerName);

    using var memoryStream = new MemoryStream();
    using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
    {
        // 获取目标Blob集合(可指定虚拟目录前缀)
        var blobQuery = string.IsNullOrEmpty(virtualDir) 
            ? containerClient.GetBlobsAsync() 
            : containerClient.GetBlobsAsync(prefix: $"{virtualDir}/");

        await foreach (var blobItem in blobQuery)
        {
            // 跳过虚拟目录本身(如果存在)
            if (blobItem.Name.EndsWith("/")) continue;

            var blobClient = containerClient.GetBlobClient(blobItem.Name);
            // 创建ZIP条目,去掉虚拟目录前缀使结构更简洁
            var zipEntryName = string.IsNullOrEmpty(virtualDir) 
                ? blobItem.Name 
                : blobItem.Name.Replace($"{virtualDir}/", "");
            var zipEntry = zipArchive.CreateEntry(zipEntryName, CompressionLevel.Optimal);

            // 将Blob内容写入ZIP条目
            using var entryStream = zipEntry.Open();
            await blobClient.DownloadToAsync(entryStream);
        }
    }
    memoryStream.Position = 0;

    // 返回ZIP文件给浏览器,自动触发下载
    return File(memoryStream, "application/zip", $"blobs_{DateTime.Now:yyyyMMddHHmmss}.zip");
}

内容的提问来源于stack exchange,提问作者Hamlet Poghosyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:31:04