简体   繁体   中英

How to get URL of file uploaded to Azure Storage via Node.js?

I am trying to retrieve the URL of the file I just uploaded to Azure Storage using node.js. My code for the upload is this:

[Notes: I'm using Ember-droplet, so the 'zone' is where files are dragged and dropped. This is the server side code to handle the route where a POST request is sent in order to upload files. ]

// 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();

    });
});

I printed out the results and response and this is what I get:

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 }

None of these seem to include the URL of the file I just posted; I'm not sure how to get the URL at all. Is there a method of blobservice I'm missing, or anything like that.

One 'solution' I found is to hardcode it with:

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

But I feel uncomfortable with that. Is there a way to extract this URL and if so, how?

It turns out that concatenating the strings is actually what the Azure library does under the hood--the destination path for your file is computed in this line:

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

...from https://github.com/Azure/azure-storage-node/blob/master/lib/common/lib/services/storageserviceclient.js . host is a marginally transformed / normalised version of exactly what you pass in as the last parameter in your call to createBlobService , and webResource.path is, again, a normalised concatenation of the blob container name and blob name you pass in the call to createBlockBlobFromFile .

Normalising all that stuff yourself reliably would be a pain, but thankfully you don't need to! Take a look at the blobService object that you're calling createBlockBlobFromFile on--there's a method getUrl . If you call this with equivalent parameters to the ones used to create your file, eg

var containerName = 'mycontainer';
var hostName = 'https://mystorageaccountname.blob.core.windows.net';

var url = blobService.getUrl(containerName, file.name, null, hostName);

...you'll get the path that a blob with the specified name, host and blob container name would end up. Not quite as handy as having the path on some returned response object, but this does look like it will reliably perform all the same normalisation and formatting on the parts of the path that it performs when making the request. Just make sure to have a single instance of both containerName and hostName shared throughout your code in that file, and you should be good.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM