如何从Azure Blob存储中查看图像,而不是下载它?

好的,所以我使用Node.js和Azure Blob存储来处理一些file upload。

当一个人上传图片时,我想向他们展示图片的缩略图。 上传工作很好,我把它存储在我的blob。

我用这个很好的链接( 在Azure SDK中为Node.js生成Azure共享访问签名和BlobService.getBlobURL() )来帮助我创build此代码来创build共享访问临时URL。

process.env['AZURE_STORAGE_ACCOUNT'] = "[MY_ACCOUNT_NAME]"; process.env['AZURE_STORAGE_ACCESS_KEY'] = "[MY_ACCESS_KEY]"; var azure = require('azure'); var blobs = azure.createBlobService(); var tempUrl = blobs.getBlobUrl('[CONTAINER_NAME]', "[BLOB_NAME]", { AccessPolicy: { Start: Date.now(), Expiry: azure.date.minutesFromNow(60), Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ }}); 

这创build一个url就好了。

例如: https:// [ACCOUNT_NAME] .blob.core.windows.net:443 / [CONTAINER_NAME] / [BLOB_NAME]?st = 2013-12-13T17%3A33%3A40Z&se = 2013-12-13T18%3A33% 3A40Z&SR = b& SP = R&SIG = Tplf5%2BG%2FsDQpRafrtVZ7j0X31wPgZShlwjq2TX22mYM%3D

问题是,当我把临时URL并插入到我的浏览器,它只会下载图像,而不是查看它(在这种情况下,它是一个简单的JPG文件)。

这转换为我的代码,我似乎无法查看它在一个标签…

链接是正确的,下载正确的文件…

有什么我需要做的来查看图像,而不是下载它?

谢谢,大卫

UPDATE

好的,所以我find了这篇文章: http : //social.msdn.microsoft.com/Forums/windowsapps/en-US/b8759195-f490-420b-a587-2bb614366ad2/embedding-images-from-blob-storage-in- SSRS报告-不-不工作

基本上它告诉我,上传时没有设置文件types,所以浏览器不知道该怎么做。

我用这里的代码: http : //www.snip2code.com/Snippet/8974/NodeJS-Photo-Upload-with-Azure-Storage/

这允许我正确地上传它,现在在浏览器中正确地浏览。

我现在的问题是,当我把tempUrl到一个img标签,我得到这个错误:

无法加载资源:服务器响应的状态为403(服务器无法validation请求,请确保授权标头的值包括签名正确形成。

这是完全相同的链接,如果我把它发布到我的浏览器它工作得很好…为什么我不能显示它在图像标签?

更新2

好吧,作为一个愚蠢的testing,我从页面加载时开始,延迟了7秒,当img标签从临时url中获取源代码时。 这似乎解决了问题(大部分时间),但显然,它是一个糟糕的解决scheme,即使它工作…

至less这validation了,因为它有时工作,我的标记至less是正确的。

我不能,为了我的生活,弄清楚为什么延迟会有一点区别…

思考?

更新3

好的,根据下面的评论,我试图将我的开始时间设置为过去约20分钟。

 var start = moment().add(-20, 'm').format('ddd MMM DD YYYY HH:mm:ss'); var tempUrl = blobs.getBlobUrl(Container, Filename, { AccessPolicy: { Start: start, Expiry: azure.date.minutesFromNow(60), Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ }}); 

我使我的开始variables的格式与azure.date.minutesFromNow相同。 它看起来像这样:星期五2013年12月13日14:53:58

当我这样做时,我甚至无法从浏览器中看到图像,更不用说img标签了。 不知道我在那里做错了什么…

更新4 – 答复

感谢荣耀@MikeWo,我有解决scheme。 正确的代码如下:

 var tempUrl = blobs.getBlobUrl('[CONTAINER_NAME]', "[BLOB_NAME]", { AccessPolicy: { Start: azure.date.minutesFromNow(-5), Expiry: azure.date.minutesFromNow(45), Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.READ }}); 

迈克是正确的,似乎有某种服务器的开始时间和我的本地主机之间的脱节,所以我需要设置在过去的开始时间。 在更新3中,我这样做了,但是Mike注意到Azure不允许开始和结束时间超过60分钟…所以在更新3中我做了-20开始和60结束,这是80分钟。

上面这个新的成功的方法使得总差值达到了50分钟,而且毫不拖延地工作。

感谢您抽出时间迈克!

简短版本:在分布式系统(包括Azure中)中存在一些时间漂移。 在创buildSAS而不是做Date.now()的开始时间的代码中,将开始时间设置为过去的一两分钟。 那么你应该能够消除延迟。

长版本:创build签名和添加Date.now的机器上的时钟可能比BLOB存储中的机器快几秒。 当对URL的请求立即进行时,BLOB服务尚未到达BLOB的“开始时间”,从而抛出403.因此,通过将开始时间设置为过去几秒钟,甚至开始如果你想要覆盖大量的时钟漂移,那么在你处理时钟漂移的时候,

更新:经过一些试验和错误:确保创build一个adhoc SAS时,不能超过一个小时。 过去几分钟设置开始时间,然后在将来60分钟过期太大。 过去一点,过了一个小时才到期。