【问题标题】:Is there an approach to force a Azure CDN file to download as a browser attachment?是否有强制 Azure CDN 文件作为浏览器附件下载的方法?
【发布时间】:2016-06-13 16:00:28
【问题描述】:

我们正在构建一个与 DAM(数字资产管理)系统集成的 ASP.NET Web 应用程序。 DAM 将文件存储在 Azure blob 存储中,并使用 Azure CDN 公开提供。

我们将提供这些文件(大部分是 PDF),以供从我们的网络应用程序下载。当用户请求其中一个文件时,我们将提供一个自定义 URL,该 URL 将在返回相关文件以供下载之前在服务器上运行一些代码(记录下载等)。

客户端要求文件始终作为浏览器附件(即内容处置附件标头)返回。我很好奇我在这里有什么选择。

我的理想是 CDN URL 是抽象的,我的自定义 URL 是文件的公共 URL。这将允许我设置相关的响应标头等。但是,我认为这里唯一的解决方案是从 CDN 下载文件并将其缓存在我的 Web 服务器上,这会混淆 CDN 的目的。因此,一旦我完成服务器处理,大概我必须将客户端重定向到 CDN 公共 URL。但是有没有一种方法可以确保 Azure 返回的文件具有正确的响应标头,以确保委派浏览器的默认下载行为?

* 更新 *

看到这个问题的答案后,我意识到我可能问错了问题。感谢那些在这里回答的人。 Follow-up question is here.

【问题讨论】:

  • 这些文件是否需要在 CDN 上?可以直接从 blob 存储提供/下载它们吗?
  • 是的,它们是最终由全球网络平台提供服务的静态资产。

标签: c# asp.net azure cdn azure-cdn


【解决方案1】:

TL;DR

您需要在 blob 存储上配置默认版本,以便它向未经过身份验证的客户端显示所需的标头。 this question 中的问题有代码让它工作。

一旦设置好,并且为匿名客户端工作,CDN 将复制所有标头,它应该可以按预期工作。

设置 ContentDisposition

该功能存在,您可以在 blob property 上设置 ContentDisposition 但是,虽然这会在 blob 上设置属性,但它不会传递到标头。

我使用以下方法在 Powershell 上对此进行了测试(只是因为它比 c# 更快)

$context = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey 

$container = Get-AzureStorageContainer -Name $ContainerName -Context $context 

$blobref = ($script:container.CloudBlobContainer.GetBlobReferenceFromServer("images/pier.jpg"))
$blobref.Properties
$blobref.Properties.ContentDisposition = 'attachment; filename="fname.ext"'  
$blobref.SetProperties()  

$blobref = ($script:container.CloudBlobContainer.GetBlobReferenceFromServer("images/pier.jpg"))
$blobref.Properties

产生(除其他外)

ContentDisposition : 附件;文件名="fname.ext"

但是查询header的时候什么都没有设置

([system.Net.HttpWebRequest]::Create($blobref.Uri.AbsoluteUri)).getresponse() 

(回答评论,。这些是返回的标题 - 在试验时我也尝试过使用和不使用内容类型 - 因此这里它是空白的)

IsMutuallyAuthenticated : False
Cookies                 : {}
Headers                 : {x-ms-request-id, x-ms-version, x-ms-lease-status, x-ms-blob-type...}
SupportsHeaders         : True
ContentLength           : 142224
ContentEncoding         : 
ContentType             : 
CharacterSet            : 
Server                  : Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
LastModified            : 01/03/2016 11:29:04
StatusCode              : OK
StatusDescription       : OK
ProtocolVersion         : 1.1
ResponseUri             : https://xxxx.blob.core.windows.net/cdn/images/pier.jpg
Method                  : GET
IsFromCache             : False

由于 CDN 只会复制 HTTP 标头本身的信息,因此这些数据不会进入 CDN。

已编辑(经过扩展的评论聊天!)

由于众所周知的原因,Powershell 没有发送 x-ms-version,所以我退回到 telnet,它确实产生了标头 -

HEAD  /cdn/images/pier.jpg HTTP/1.1
HOST: xxxx.blob.core.windows.net
x-ms-version: 2015-04-05

HTTP/1.1 200 OK
Content-Length: 142224
Last-Modified: Tue, 01 Mar 2016 11:29:04 GMT
Accept-Ranges: bytes
ETag: "0x8D341C4B1C4F34F"
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: b4f41b01-0001-00d7-7cc9-7384c9000000
x-ms-version: 2015-04-05
x-ms-lease-status: unlocked
x-ms-lease-state: available
x-ms-blob-type: BlockBlob
Content-Disposition: attachment; filename="fname.ext"
Date: Tue, 01 Mar 2016 14:49:17 GMT

【讨论】:

  • 我认为 Azure 存储没有任何问题。我相信您测试此功能的方式是不正确的。我认为HttpWebRequest 不会真正启动文件下载。它会简单地将 blob 的内容作为字节流读取并呈现给客户端。当您设置 content-disposition 标头时,启动下载的是浏览器。当您在浏览器中输入您的 blob URL 时会发生什么(当然 blob 需要公开可用)?会被下载吗?
  • @GauravMantri 我已将HttpWebRequest 返回的标题添加到问题中-实际上我也尝试了其他几种方法,没有显示简单的数据-显然我们不在乎此时是否下载,只是是否存在正确的标头。在这种情况下,ContentDisposition 标头没有像预期的那样出现(在rfc2183 中)当在浏览器中查看时,图像会正常显示。代码在那里,如果您觉得我遗漏了什么,请随时修改。
  • 您没有看到此标头的原因是您没有在 HTTP 请求中指定存储服务版本。因为您没有指定存储服务版本,所以存储服务会选择默认版本(2009-09-19 或类似的版本)。在存储服务 REST API 的更高版本中添加了 Content-Disposition 标头。尝试以下类似的操作,您将看到此标头被返回: $req = ([system.Net.HttpWebRequest]::Create($blobref.Uri.AbsoluteUri)) $req.Headers.Add('x-ms-version ', '2015-04-05') $response = $req.getresponse()
  • @GauravMantri Chrome 等人怎么样?在请求中指定存储版本?他们不知道存储的内容或位置,他们只是执行 HTTP 1.1 获取请求。 - 在 Powershell cmdlet 上运行调试请求显示 api-version=2015-06-15 Get Blob Properties 需要 2013-08-15 - 据我所知,ContentDisposition 未反映在标头中。不管他们怎么称呼。您的代码还会导致报告相同的标题。
  • 他们没有。来自msdn.microsoft.com/en-us/library/azure/dd894041.aspxIf a request to the Blob service does not specify the x-ms-version header, and the default version for the service has not been set using Set Blob Service Properties, then the earliest version of the Blob service is used to process the request. However, if the container was made public with a Set Container ACL operation performed using version 2009-09-19 or newer, then the request is processed using version 2009-09-19.
猜你喜欢
  • 2017-11-04
  • 2011-09-25
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 2010-12-27
  • 2018-05-15
  • 2015-04-16
  • 1970-01-01
相关资源
最近更新 更多