Azure Blob Storage | How To Upload An Image With Javascript

Can you upload an image to azure blob storage with javascript?

Sometimes when building a new website or application and using the Microsoft Azure Cloud for the backend components, there is a requirement to allow users or customers to upload their images to an Azure Blob Storage account for later use. Instead of using a custom passthrough API endpoint for doing the upload, you may wonder if you can upload an image directly with your javascript front end code.

Customer images can be uploaded directly to an Azure Blob Storage account using the v12 Azure Blob Storage javascript client library for the browser. Using this library, front end code is able to upload and fetch files directly with the browser when using a valid shared access signature.

This post will go over the required setup and configuration for accomplishing this task as well as showing the individual steps that are needed to upload an image directly from the users browser to the blob storage account. You’ll also see how more blob storage tasks can be accomplished with this javascript client library as well, as long as the required credentials are provided to the shared access signature.

Azure Blob Storage CORS Configuration

The first thing that needs to be setup to be able to upload files directly to the blob storage account are the CORS rules. These can be configured by visiting the Azure portal and going to the storage account that you would like to upload images to. Once there, there should be a CORS tab on the left hand side. Once selected a new panel will open up which will allow you to configure the CORS settings of this storage account. Under the Blob Service tab add a new entry.

For the allowed origins, you will likely want to put the domain that your frontend UI is configured to use. However for the purpose of this article, we’ll use *, which would allow any domain to upload to the storage account. For allowed methods, this setting will really depend on what storage account functionality that you want your front end code to be able to accomplish. Since this article is simply about uploading images to the storage account, we will simply check the PUT option. The Allowed Headers and Exposed Headers should also be tuned for specifically the headers that are required for the functionality that you want the UI to offer, but to make things easy we are also going to set this to *. The final setting to configure is the Max Age. For our purposes we will set the value to a full day, or 86400 seconds. Make sure to click Save in the top menu bar to persist these settings.

Azure Blob Storage Javascript Client Library v12 SDK

Microsoft Azure provides several different libraries and software development kits for their storage services in many different programming languages. In order to use front end code like javascript to work with the Blob Storage account, you’ll want to use one of their latest javascript client library to accomplish the task. You can use this library with pretty much any javascript front end framework that you like, but for the purposes of this article, we are just going to use a simple node.js project. The instructions below will setup the project and install some required libraries as well as show some changes required for the package.json file to work with most browsers.

Initial Project Setup

npm init -y
npm install --save @azure/storage-blob
npm install -g parcel-bundler

Updated package.json

{
"name": "uploadjs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"browserslist": [
"last 1 Edge version",
"last 1 Chrome version",
"last 1 Firefox version"
],
"dependencies": {
"@azure/storage-blob": "^12.2.0-preview.1"
}
}

Next we need a simple HTML file which will be used to select the image file to be uploaded directly to blob. Again this should be done using your frontend framework of choice instead of writing the raw HTML shown below, but this is just to give an idea of what is needed. We are also including the index.js file, which is defined later, in the body of this HTML file.

<!DOCTYPE html>
<html>
<body>
<button id="select-button">Select files</button>
<input type="file" id="file-input" multiple style="display: none;" />
<script src="index.js"></script>
</body>
</html>

Now we need to create the javascript source code to go along with the above form so that the Azure Blob Storage javascript SDK client can be used to upload the selected files to the correct blob storage account. This is just an example of how this can be accomplished with the Azure javascript client SDK and it should be adapted for your framework of choice.

import 'regenerator-runtime/runtime'
const { BlobServiceClient } = require('@azure/storage-blob');

const selectButton = document.getElementById('select-button');
const fileInput = document.getElementById('file-input');

const blobSasUrl = 'GET A SAS URL FROM THE AZURE PORTAL OR AZURE CLI';
const blobServiceClient = new BlobServiceClient(blobSasUrl);

const containerName = 'demo';
const containerClient = blobServiceClient.getContainerClient(containerName);

const uploadFiles = async () => {

try {
const promises = [];
for (const file of fileInput.files) {
const blockBlobClient = containerClient.getBlockBlobClient(file.name);
promises.push(blockBlobClient.uploadBrowserData(file));
}
await Promise.all(promises);
alert('Done.');
}
catch (error) {
alert(error.message);
}
}

selectButton.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', uploadFiles);

You’ll notice that a fake value is being used for the blobSasUrl in the code above. In order to properly fill this in, one will need to be generated from the Azure Portal, the Azure CLI, or the Azure API. Normally the frontend UI would request an shared access token which is provisioned specifically for the container and file name of the file to be uploaded, so that the signature can only ever be used to upload a file to that specific location. This shared access signature should also have a time limit configured on it so that it will only work for a small range of time. Otherwise, if the signature was somehow exposed to a third party, they could overwrite the file or image that was uploaded by the client.

The shared access signature can be generated in the Azure Portal by going to the storage account that the images should be uploaded to, and selecting the Shared access signatures tab on the left hand side. From there different settings can be configured for the signature including the allowed services, the allowed resource types, the allowed permissions, the start and expiry times, allowed IP address ranges, allowed protocols and which signing key to use to generate the signature. These settings should be tuned specifically for the use case that the shared access signature is being used to accomplish.

Uploading An Image with Azure Blob Storage Javascript Client SDK

Now that we have all of the required code written we are ready to get things setup and running so that we can test uploading a file directly to the Azure Blob Storage container. To do this though, we first need to package everything up so that they can be hosted with a small local server. Again this will likely be different from how you would do this as you’re likely running a different javascript framework than this example. In this case we are using the parcel tool to host things for local testing.

parcel index.html

Now that this has happened, you can visit http://localhost:1234 and from here you can select an image by clicking the Select files button and choosing the image that you would like to upload to the Azure Blob Storage container. If everything went well, you’ll get an alert popup that says Done. which means that the image was successfully uploaded to the Azure Blob Storage container from the web page loaded by the browser.

The video below also shows the entire process of setting up and running these small pieces of code in order to upload data directly to the Azure Blob Storage container from the browser. Please like and subscribe!