Upload to Azure Blob Storage using a Web Browser
Post by: syed hussain in All Microsoft Azure
Summary
This post demonstrates how to create a web application that uploads files to Azure Blob Storage. The web application is a plain node.js application which can be uploaded to Azure Container Apps or uploaded as a Web App.
Setup Storage Account
- Create a new Storage Account.
- Enable the following under the Resource Sharing (CORS) options in the storage account:
Allowed Origins: *
Allowed Methods: DELETE,GET,HEAD,MERGE,POST,OPTIONS,PATCH,PUT
Allowed Headers: *
Exposed Headers: *
Max Age: 86400
- Generate a SAS URL from the Container. In the example below, I will select Object under the Allowed resource types.
Copy and store the SAS URL.
Setup Node.js
The Node.js project will have the following file structure:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 29/04/2022 17:54 .parcel-cache
d----- 29/04/2022 17:54 dist
d----- 29/04/2022 17:54 node_modules
-a---- 29/04/2022 17:46 739 index.html
-a---- 29/04/2022 17:53 4012 index.js
-a---- 29/04/2022 17:54 173597 package-lock.json
-a---- 29/04/2022 17:54 506 package.json
Install Packages
- Create a new directory called ‘BlobFileUpload’.
- Run command:
npm init -y
npm install @azure/storage-blob
npm install parcel
- Update the package.json file to:
{
"name": "blobupload",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "parcel ./index.html"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@azure/storage-blob": "^12.9.0",
"parcel": "^2.5.0"
},
"browserslist": [
"last 1 Edge version",
"last 1 Chrome version",
"last 1 Firefox version",
"last 1 safari version",
"last 1 webkit version"
],
"devDependencies": {
"buffer": "^6.0.3"
}
}
Create index.html & index.js
index.html
Create an index.html file in the root directory.
<!-- index.html -->
<!DOCTYPE html>
<html>
<body>
<button id="create-container-button">Create container</button>
<button id="select-button">Select and upload files</button>
<input type="file" id="file-input" multiple style="display: none;" />
<button id="list-button">List files</button>
<button id="delete-button">Delete selected files</button>
<button id="delete-container-button">Delete container</button>
<p><b>Status:</b></p>
<p id="status" style="height:160px; width: 593px; overflow: scroll;" />
<p><b>Files:</b></p>
<select id="file-list" multiple style="height:222px; width: 593px; overflow: scroll;" />
</body>
<script type="module" src="./index.js"></script>
</html>
index.js
Update the const blobSasUrl with the SAS URL you created earlier.
const { BlobServiceClient } = require("@azure/storage-blob");
const createContainerButton = document.getElementById("create-container-button");
const deleteContainerButton = document.getElementById("delete-container-button");
const selectButton = document.getElementById("select-button");
const fileInput = document.getElementById("file-input");
const listButton = document.getElementById("list-button");
const deleteButton = document.getElementById("delete-button");
const status = document.getElementById("status");
const fileList = document.getElementById("file-list");
const reportStatus = message => {
status.innerHTML += `${message}<br/>`;
status.scrollTop = status.scrollHeight;
}
// Update <placeholder> with your Blob service SAS URL string
const blobSasUrl = "<SAS URL>";
// Create a new BlobServiceClient
const blobServiceClient = new BlobServiceClient(blobSasUrl);
// Create a unique name for the container by
// appending the current time to the file name
const containerName = "container" + new Date().getTime();
// Get a container client from the BlobServiceClient
const containerClient = blobServiceClient.getContainerClient(containerName);
// Create
const createContainer = async () => {
try {
reportStatus(`Creating container "${containerName}"...`);
await containerClient.create();
reportStatus(`Done.`);
} catch (error) {
reportStatus(error.message);
}
};
const deleteContainer = async () => {
try {
reportStatus(`Deleting container "${containerName}"...`);
await containerClient.delete();
reportStatus(`Done.`);
} catch (error) {
reportStatus(error.message);
}
};
createContainerButton.addEventListener("click", createContainer);
deleteContainerButton.addEventListener("click", deleteContainer);
// List
const listFiles = async () => {
fileList.size = 0;
fileList.innerHTML = "";
try {
reportStatus("Retrieving file list...");
let iter = containerClient.listBlobsFlat();
let blobItem = await iter.next();
while (!blobItem.done) {
fileList.size += 1;
fileList.innerHTML += `<option>${blobItem.value.name}</option>`;
blobItem = await iter.next();
}
if (fileList.size > 0) {
reportStatus("Done.");
} else {
reportStatus("The container does not contain any files.");
}
} catch (error) {
reportStatus(error.message);
}
};
listButton.addEventListener("click", listFiles);
// Upload
const uploadFiles = async () => {
try {
reportStatus("Uploading files...");
const promises = [];
for (const file of fileInput.files) {
const blockBlobClient = containerClient.getBlockBlobClient(file.name);
promises.push(blockBlobClient.uploadBrowserData(file));
}
await Promise.all(promises);
reportStatus("Done.");
listFiles();
}
catch (error) {
reportStatus(error.message);
}
}
selectButton.addEventListener("click", () => fileInput.click());
fileInput.addEventListener("change", uploadFiles);
// Delete
const deleteFiles = async () => {
try {
if (fileList.selectedOptions.length > 0) {
reportStatus("Deleting files...");
for (const option of fileList.selectedOptions) {
await containerClient.deleteBlob(option.text);
}
reportStatus("Done.");
listFiles();
} else {
reportStatus("No files selected.");
}
} catch (error) {
reportStatus(error.message);
}
};
deleteButton.addEventListener("click", deleteFiles);
Result
Run the following command to start the server.
npm start
The following page should run:
Test with the following actions:
- Create container.
- Select and Upload files.
- List files
- Delete selected files.
- Delete container.
Each action should result in a change to Azure Blob Storage.
Tags: azure storage blob upload files