如何通过Node.js获取上传到Azure存储的文件的URL?

时间:2014-06-30 15:02:25

标签: javascript node.js azure ember.js

我正在尝试使用node.js检索刚刚上传到Azure存储的文件的URL。我上传的代码是:

[注意:我正在使用Ember-droplet,因此'zone'是拖放文件的位置。这是服务器端代码,用于处理发送POST请求以上载文件的路由。 ]

// Responsible for the call to OPTIONS.
app.options('/upload', function(request, response) {
    response.send(200);
});

/* Responsible for file upload. */
app.post('/fileUpload', function(request, response) {

    /* Get the files dropped into zone. */
    var files       = request.files.file,
        promises    = [];

    /**
     * @method uploadFile
     * @param file {Object}
     * @return {Object}
     * Function takes a general param file, creates a blob from it and returns the promise to upload it.
     * Promise: jQuery promise = all done later. 
     */
    var uploadFile = function(file) {
        var deferred = new Deferred();

        // Actual upload code.
        // Also replace 'profile-pictures with abstracted container name.'
        blobService.createBlockBlobFromFile('profile-pictures', file.name, file.path, function(error, result, response) {
            if (!error) {
                deferred.resolve(file.name);
                console.log("result:");
                console.log(result);

                console.log("response:");
                console.log(response);
            }
        });

        return deferred.promise;
    };

    if (!Array.isArray(files)) {

        // We're dealing with only one file.
        var promise = uploadFile(files);
        promises.push(promise);

    } else {

        // We're dealing with many files.
        files.forEach(function(file) {
            var promise = uploadFile(file);
            promises.push(promise);
        });

    }

    var fileUrls = [];
    // Send all files in the promise to execute.
    promisedIo.all(promises).then(function(files) {
            response.send({ files: files, success: true });
            response.end();

    });
});

我打印出结果和回复,这就是我得到的:

result:
{ container: 'profile-pictures',
  blob: 'robot.jpeg',
  etag: '---blah---',
  lastModified: 'Mon, 30 Jun 2014 14:38:09 GMT',
  contentMD5: '---blah---',
  requestId: '---blah---' }
response:
{ isSuccessful: true,
  statusCode: 201,
  body: '',
  headers: 
   { 'transfer-encoding': 'chunked',
     'content-md5': '---blah---',
     'last-modified': 'Mon, 30 Jun 2014 14:38:09 GMT',
     etag: '"---blah---"',
     server: 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0',
     'x-ms-request-id': '---blah---',
     'x-ms-version': '2014-02-14',
     date: 'Mon, 30 Jun 2014 14:38:08 GMT' },
  md5: undefined }

这些似乎都没有包含我刚发布的文件的网址;我不确定如何获取URL。有没有一种blobservice我缺少的方法,或类似的东西。

我找到的一个'解决方案'是硬编码:

HTTP:///blob.core.windows.net//blob-name,

但我对此感到不舒服。有没有办法提取这个URL,如果有,怎么做?

1 个答案:

答案 0 :(得分:5)

事实证明,连接字符串实际上是Azure库所做的工作 - 文件的目标路径在此行中计算:

webResource.uri = url.resolve(host, url.format({pathname: webResource.path, query: webResource.queryString}));

...来自https://github.com/Azure/azure-storage-node/blob/master/lib/common/lib/services/storageserviceclient.jshost是一个略微转换/规范化的版本,正好是您在调用createBlobService时传入的最后一个参数,而webResource.path再次是blob容器名称的规范化并置您在调用createBlockBlobFromFile时传递的blob和blob名称。

将所有这些东西可靠地归一化会很痛苦,但幸运的是你不需要!请查看您正在调用blobService的{​​{1}}对象 - 其中包含createBlockBlobFromFile方法。如果使用与创建文件相同的参数调用此参数,例如

getUrl

...您将获得具有指定名称,主机和blob容器名称的blob最终的路径。不像在某些返回的响应对象上使用路径那样方便,但这看起来确实会在发出请求时执行的路径部分上可靠地执行所有相同的规范化和格式化。只需确保在该文件的代码中共享var containerName = 'mycontainer'; var hostName = 'https://mystorageaccountname.blob.core.windows.net'; var url = blobService.getUrl(containerName, file.name, null, hostName); containerName的单个实例,您就应该做得很好。