0

We use Azure Mobile Services with Javascript (Node.js) back-end. The front-end is HTML/Javascript and runs as Azure Web App. We want to use Azure blob storage to store files (uploaded from front-end). I searched for a working example implementing this scenario, but I can't find it. There are examples with .NET back-end or Android/Windows Phone front-end. As a workaround it's possible to post the file to mobile service and do the storage from there, but the mobile service api body has a 1MB limit. I know I have to use a Shared Access Signature (SAS), but I don't know how to implement that. Generating the url from mobile service works. But it's not accepted when I use it in the client.

This guide is not working anymore: http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/

Thanks in advance for your help!

Peter Pan
  • 23,476
  • 4
  • 25
  • 43
  • if your frond-end has code on server side, you can easily use azure storage SDK to generate SAS and talk to Azure storage https://github.com/Azure/azure-storage-node (i assume you are running nodejs) – Xiaomin Wu Nov 17 '15 at 16:52
  • Hi Xiaomin, server side is Azure Mobile Services with JavaScript (node.js). It's possible to generate SAS there with the Azure storage SDK, but it doesn't work when I use this SAS on the frontend (plain JavaScript). Authorization errors. – Jeroen Custers Nov 17 '15 at 19:45
  • if you are trying to access azure stroage from your client side javascript code directly, you will hit cross origin issue. you will need to config your storage account i believe. https://msdn.microsoft.com/en-us/library/azure/dn535601.aspx?f=255&MSPPError=-2147217396 – Xiaomin Wu Nov 17 '15 at 21:17
  • Yes CORS is also an issue, but even when I use chrome with --disable-web-security I get authentication errors (Authorization header signature) – Jeroen Custers Nov 18 '15 at 13:55
  • Did you configure your storage account? to enable CORS, you need to have CORS rules in your acccount. please refer to the link i post above – Xiaomin Wu Nov 18 '15 at 18:14
  • I have CORS rules implemented, but it still doesn't work. – Jeroen Custers Nov 19 '15 at 09:03
  • when you say "doesn`t work". do you see a different error? will be good if there is some network trace. there must be something wrong on your code i think. see another discussion here where it discuss about how to access Queue storage http://stackoverflow.com/questions/24691018/how-to-access-azure-storage-queue-by-javascript – Xiaomin Wu Nov 19 '15 at 19:41

1 Answers1

1

As usually, custom APIs on mobile services are used in handling logic workflows or event triggers. So Azure mobile service limit the body size of custom APIs requests for better performance. To implement upload files from clients to Azure Storage, we recommend to leverage SAS URIs.

And lots samples use the backend project to generate the SAS URI and return back to front-end.We can leverage Azure Node.js SDK in Mobile service custom APIs scripts to generate SAS URI.

Here is the code snippet:

exports.get = function(request, response) {
    var azure = require('azure');
    var qs = require('querystring');
    var accountName = { accountName };
    var accountKey = { accountKey };
    var host = accountName + '.blob.core.windows.net';
    var blobService = azure.createBlobService(accountName, accountKey, host);

    var startDate = new Date();
    var expiryDate = new Date(startDate);
    expiryDate.setMinutes(startDate.getMinutes() + 30);
    startDate.setMinutes(startDate.getMinutes() - 30);

    var sharedAccessPolicy = {
      AccessPolicy: {
        Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
        Start: startDate,
        Expiry: expiryDate
      },
    };
    // you can custom send container name and blob name via http get request
    /** e.g. var containerName = request.query.container, 
                 blobName = request.query.blob

        client side use invokeApi method, e.g.
        client.invokeApi('getSAS',{
            method:'GET',
            parameters:{container:'mycontainer',blob:'myblob'}
        })
    **/
    var blobSAS = blobService.generateSharedAccessSignature('mycontainer', 'myblob', sharedAccessPolicy);
    var sasQueryString = qs.stringify(blobSAS.queryString);
    var sasUri = blobSAS.baseUrl + blobSAS.path;
    response.send(sasUri+"?"+sasQueryString);
}; 

You can refer to Upload images to Azure Storage from an Android device and Work with a JavaScript backend mobile service for reference.

Furthermore, for a deep understanding of generating SAS URI, you can refer to Constructing a Service SAS and Shared Access Signatures, Part 1: Understanding the SAS Model

Additionally, here is a similar example built in this architecture, Upload files to Microsoft Azure Storage from JavaScript

Gary Liu
  • 13,758
  • 1
  • 17
  • 32