Azure Storage Blob upload from browser

Many web application needs end-users to upload files for processing. And these files need to be stored in a persisted storage. One common practice is, developers write code to upload the file and save it on the webserver itself. This approach is OK if the file size is small and/or smaller number of uploads. Recommended approach is, let the browse upload the files to Azure Storage directly without need to talk to webserver. This option, frees up webserver for other business processing.

For browser to talk to Azure Storage, instead of exposing storage connection string, we can use SAS Key (Share Access Security). SAS key is valid only for limited time and has specific permissions like write but not read or list. For more details on SAS keys please see here

Here is quick sample to upload blob files to Azure Storage from a browser directly and then process it the server side.

  1. Blob files are uploaded directly from browser to Storage using SAS Key
  2. Browser sends the blob file name to Web server
  3. Web server access blob using connection string

image

1. Download JavaScript Client library for Azure Storage

2. Generate SAS token

  1. Log into Azure portal https://portal.Azure.com
  2. Navigate to your Storage Account
  3. Click on the Share Access Signature
  4. Select write only as shown below and click Generate SAS token button
  5. Copy SAS token
  6. Note : you may have to change expiry date/time if you are planning to use this SAS key for longer duration
    image

3. Enable CORS

  1. Log into Azure Portal https://portal.azure.com
  2. Navigate to your Azure Storage account
  3. Click on CORS
  4. Set these following values and hit Save button
    image

4. Client side code

  1. Extract the above zip file and copy the azure-storage.blob.min.js to your application scripts folder. For ASP.NET MVC application, you can copy it to Script folder as shown below

    image

  2. In your client side code, add these lines

<script src="~/Scripts/azure-storage.blob.min.js">
//this Azure Storage JavaScript Client Library
</script>
 
<p>Select file to upload to blob</p>
<p>
     
</p>
<p>
    <button>Upload to blob</button>
</p>
<p>
    <button>Do server side processing </button>
</p>
 
 
    <script>
 
        var blobname;
        function blobUpload() {
   // blob client
            var blobUri = 'https://STORAGENAME.blob.core.windows.net';
            var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, 'SASKEY');
 
            // blob upload
            var file = document.getElementById('blobFile').files[0];
 
            var customBlockSize = file.size &gt; 1024 * 1024 * 32 ? 1024 * 1024 * 4 : 1024 * 512;
            blobService.singleBlobPutThresholdInBytes = customBlockSize;
 
            var filename = file.name.substring(0, file.name.lastIndexOf('.'));
            var ext = file.name.substring(file.name.lastIndexOf('.'));
 
            blobname = filename + '_' + Math.random().toString(16).slice(2) + ext;
 
            var speedSummary = blobService.createBlockBlobFromBrowserFile('CONTAINER', blobname, file, { blockSize: customBlockSize }, function (error, result, response) {
                if (error) {
                    // Upload blob failed
                    alert("blob upload failed : check CORS");
                } else {
                    // Upload successfully
                    alert("blob upload successfull");
                }
            });
 
            var bcheckList = false;
            if (bcheckList) {
                // blob list
                blobService.listBlobsSegmented('CONTAINER', null, function (error, results) {
                    if (error) {
                        // List blobs error
                        alert("blob list failed : check SAS token");
                    } else {
                        for (var i = 0, blob; blob = results.entries[i]; i++) {
                            // blob object
                            alert("blob found : " + blob);
                        }
                    }
                });
            }
        }
 
        function serverside() {
            var newURL = location.protocol + "//" + location.host + "/Home/Contact?id=" + blobname;
            newURL = encodeURI(newURL)
            //alert(newURL);
            window.location = newURL;
        }
 
    </script>   

5. Server side code

  1. Add following code on your server side

    
    public ActionResult Contact(string id)
    {
    // id is blob file name
        CloudStorageAccount storageAccount = null;
    
        CloudBlobContainer cloudBlobContainer = null;
    
        var storageConnectionString = "CONNECTION STRING TO STORAGE";
        CloudStorageAccount.TryParse(storageConnectionString, out storageAccount);
    
        CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
    
        cloudBlobContainer = cloudBlobClient.GetContainerReference("CONTAINER");
    
        CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(id);
    
        ViewBag.Message = "Your contact page.";
    
        return View();
    }