如何为单个 azure blob 请求设置内容处置?

Posted

技术标签:

【中文标题】如何为单个 azure blob 请求设置内容处置?【英文标题】:How to set content disposition on individual azure blob requests? 【发布时间】:2018-02-06 14:09:31 【问题描述】:

我有一个托管视频的应用程序,我们最近迁移到了 Azure。

在我们的旧应用程序中,我们为用户提供了播放或下载视频的功能。但是在 Azure 上,我似乎必须在我想要的功能之间进行选择,因为必须在文件上而不是在请求上设置内容处置。

到目前为止,我提出了两个非常糟糕的解决方案。

第一个解决方案是通过我的 MVC 服务器流式下载。

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
                        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                        CloudBlobContainer container = blobClient.GetContainerReference("videos");
                        string userFileName = service.FirstName + service.LastName + "Video.mp4";
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + userFileName); // force download
                        container.GetBlobReference(service.Video.ConvertedFilePath).DownloadToStream(Response.OutputStream);
                        return new EmptyResult();

此选项适用于较小的视频,但对我的服务器来说非常费力。对于较大的视频,操作会超时。

第二个选项是将每个视频托管两次。

这个选项显然不好,因为我将不得不支付双倍的存储成本。

【问题讨论】:

【参考方案1】:

但在 Azure 上,我似乎必须在哪一个之间做出选择 我想要的功能,因为必须在 文件而不是请求。

有一个解决方法。您可能知道有一个 Content-Disposition 可以在 blob 上定义的属性。但是,当您为此属性定义值时,它将始终应用于该 blob。当您想在 blob 上选择性地应用此属性时(例如基于每个请求),您所做的是在该 blob 上创建一个 Shared Access Signature (SAS) 并在那里覆盖此请求标头。然后您可以通过 SAS URL 提供 blob。

这是示例代码:

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("videos");
        string userFileName = service.FirstName + service.LastName + "Video.mp4";
        CloudBlockBlob blob = container.GetBlockBlobReference(userFileName);
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
        
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1)
        ;
        SharedAccessBlobHeaders blobHeaders = new SharedAccessBlobHeaders()
        
            ContentDisposition = "attachment; filename=" + userFileName
        ;
        string sasToken = blob.GetSharedAccessSignature(policy, blobHeaders);
        var sasUrl = blob.Uri.AbsoluteUri + sasToken;//This is the URL you will use. It will force the user to download the video.

我很久以前写了一篇博文,您可能会觉得有用:http://gauravmantri.com/2013/11/28/new-changes-to-windows-azure-storage-a-perfect-thanksgiving-gift/。

【讨论】:

非常感谢!!!【参考方案2】:

据我所知,azure blob storage 不支持将自定义标头添加到特殊容器中。

我建议您可以关注并投票feedback 以推动 azure 开发团队支持此功能。

这是一种解决方法,您可以先压缩视频文件,然后上传到 azure blob 存储。

它不会被浏览器打开。

【讨论】:

以上是关于如何为单个 azure blob 请求设置内容处置?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Azure 上的 Node.js Api 应用启用 BLOB 日志记录?

Azure 存储 API 内容处置

如何为 Azure Blob 存储中的文件夹生成共享访问签名?

使用 powershell 将两个 azure blob 合并为单个 blob

Ionic Zip 密码设置在 azure blob 存储中,并为 zip 文件夹而不是文件设置最佳压缩

如何为单个 HttpsURLConnections 设置 https.proxyHost 和 https.proxyPort?