node.js - 如何从 Azure Blob 存储查看图像而不是下载图像?

标签 node.js azure azure-blob-storage

好的,我正在使用 Node.js 和 Azure Blob 存储来处理一些文件上传。

当一个人上传图像时,我想向他们显示图像的缩略图。上传效果很好,我已将其存储在我的 blob 中。

我使用这个精细链接 ( Generating Azure Shared Access Signatures with BlobService.getBlobURL() in Azure SDK for Node.js ) 来帮助我创建此代码来创建共享访问临时 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
}});

这样就可以创建一个 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 文件)。

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

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

我需要做些什么才能查看图像而不是下载图像吗?

谢谢, 大卫

更新

好的,所以我找到了这篇文章: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/b8759195-f490-420b-a587-2bb614366ad2/embedding-images-from-blob-storage-in-ssrs-report-does-not-work

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

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

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

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

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

这与我将其发布到浏览器时的链接完全相同...为什么我不能在图像标签中显示它?

更新2

好吧,作为一个愚蠢的测试,我在页面加载时和 img 标签从临时 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
}});

我将开始变量的格式设置为与 azure.date.minesFromNow 相同的格式。它看起来像这样: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
}});

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

我上面的新的、成功的方法使总时间缩短了 50 分钟,而且完全没有任何延迟。

感谢您抽出时间迈克!

最佳答案

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

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

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

关于node.js - 如何从 Azure Blob 存储查看图像而不是下载图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20572726/

相关文章:

c# - .NET Core 2.0 MVC 文件上传进度

python - 如何获取容器中各级的所有 Blob?

javascript - MongoError,错误 :E11000 duplicate key error

node.js - 是否可以将用户从我的 mongodb 数据库迁移到 aws cognito 用户池?

azure - 发布到 Azure 的机器人出现内部服务器错误

azure - 如何预先检测Azure ARM脚本是否会更改customData?

javascript - 为什么 socketIO 调用太多连接?

node.js - 使用除 ObjectId 以外的 SchemaTypes 来填充 (Mongoose)

azure - 使用 CLI 启用 Azure 诊断日志记录

azure - 将 Blob 存储挂载为 VM 上的驱动器