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

Dav*_*vid 8 azure azure-storage-blobs node.js

好的,所以我使用Node.js和Azure Blob Storage来处理一些文件上传.

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

我使用这个很好的链接(在Azure SDK for Node.js中使用BlobService.getBlobURL()生成Azure共享访问签名)来帮助我创建此代码以创建共享访问临时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
}});
Run Code Online (Sandbox Code Playgroud)

这创建了一个网址就好了.

这样的事情: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

问题是当我拿到临时网址并将其插入我的浏览器时,它只会下载图像而不是查看它(在这种情况下它是一个简单的jpg文件).

这转换为我的代码,我似乎无法在标签中查看它...

链接正确,下载正确的文件......

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

谢谢,大卫

UPDATE

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

基本上它告诉我在上传时没有设置文件类型,因此浏览器不知道如何处理它.

我使用了以下代码:http://www.snip2code.com/Snippet/8974/NodeJS-Photo-Upload-with-Azure-Storage/

这使我能够正确上传它,现在可以在浏览器中正确查看.

我现在遇到的问题是,当我将tempUrl放入img标签时,我收到此错误:

无法加载资源:服务器响应状态为403(服务器无法验证请求.请确保正确形成Authorization标头的值,包括签名.)

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

更新2

好吧,所以作为一个愚蠢的测试,我从我的页面加载和img标签从temp url获取源时延迟了7秒.这似乎解决了这个问题(大部分时间),但它显然是一个糟糕的解决方案,即使它工作...

至少这会验证,因为它有时起作用,我的标记至少是正确的.

对于我的生活,我不能弄清楚为什么延迟会有所不同......

思考?

更新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
}});
Run Code Online (Sandbox Code Playgroud)

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

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

更新4 - 答案

感谢光荣的@MikeWo,我有解决方案.正确的代码如下:

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
}});
Run Code Online (Sandbox Code Playgroud)

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

我上面新的,成功的方式使总差异达到50分钟,并且它完全没有任何延迟.

谢谢你抽出时间迈克!

Mik*_*eWo 3

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

长版本:创建签名和添加 Date.now 的计算机上的时钟可能比 BLOB 存储中的计算机快几秒钟。当立即向 URL 发出请求时,BLOB 服务尚未达到 BLOB 的“开始时间”,因此会抛出 403。因此,通过将开始时间设置为过去几秒,甚至是开始时间今天,如果你想解决巨大的时钟漂移问题,你需要建立对时钟漂移的处理能力。

更新:经过一些尝试和错误:确保创建临时 SAS 时的时间不能超过一个小时。将开始时间设置为过去几分钟,然后将到期时间设置为未来 60 分钟,这太大了。让它过去一点,然后不到一个小时就到期了。