This guide demonstrates how to upload files directly to Azure Blob Storage using only client-side HTML, CSS, and JavaScript. This approach is particularly useful for single-page applications (SPAs) or scenarios where you want to offload file uploads from your backend server.
Prerequisites:
Navigate to your Blob container in the Azure portal. Select "Generate SAS". Configure the permissions to include "Write" and set an appropriate expiry time. Copy the generated SAS token (which includes the signature and expiry) and the Blob service endpoint URL of your storage account.
Important: Treat your SAS token like a password. For production environments, consider generating SAS tokens server-side with stricter expiration policies.
Use an HTML file input element to allow users to select files. We'll use JavaScript to handle the upload process.
Example HTML Structure:
<div id="uploadSection">
<h2>Upload Your File</h2>
<div class="file-input-wrapper" id="dropArea">
<i class="fas fa-upload"></i>
<label for="fileUpload">Drag and drop a file here, or click to select a file</label>
<input type="file" id="fileUpload">
</div>
<button id="uploadButton" disabled>Upload to Azure Blob Storage</button>
<div id="uploadStatus" class="upload-status">
<span id="statusMessage"></span>
<div class="progress-bar-container">
<div class="progress-bar" id="progressBar"></div>
</div>
</div>
</div>
The JavaScript code will:
Example JavaScript Snippet:
// --- Configuration ---
const AZURE_STORAGE_ACCOUNT_URL = 'YOUR_STORAGE_ACCOUNT_BLOB_ENDPOINT_URL'; // e.g., https://mystorageaccount.blob.core.windows.net
const CONTAINER_NAME = 'your-container-name';
const SAS_TOKEN = '?sv=2020-08-04&ss=bfqt&srt=sco&sp=w&se=YYYY-MM-DDTHH:MM:SSZ&st=YYYY-MM-DDTHH:MM:SSZ&spr=https&sig=YOUR_SAS_SIGNATURE'; // Include the '?'
// --- DOM Elements ---
const fileInput = document.getElementById('fileUpload');
const uploadButton = document.getElementById('uploadButton');
const statusMessage = document.getElementById('statusMessage');
const uploadStatusDiv = document.getElementById('uploadStatus');
const progressBar = document.getElementById('progressBar');
const dropArea = document.getElementById('dropArea');
let selectedFile = null;
// --- Event Listeners ---
fileInput.addEventListener('change', handleFileSelect);
uploadButton.addEventListener('click', handleUpload);
// Drag and Drop Functionality
dropArea.addEventListener('dragover', (e) => {
e.preventDefault();
dropArea.style.borderColor = '#0078d4';
});
dropArea.addEventListener('dragleave', () => {
dropArea.style.borderColor = '#ccc';
});
dropArea.addEventListener('drop', (e) => {
e.preventDefault();
dropArea.style.borderColor = '#ccc';
const files = e.dataTransfer.files;
if (files.length) {
handleFile(files[0]);
}
});
function handleFileSelect(event) {
const files = event.target.files;
if (files.length) {
handleFile(files[0]);
}
}
function handleFile(file) {
selectedFile = file;
const fileNameLabel = dropArea.querySelector('label');
fileNameLabel.textContent = `Selected: ${file.name} (${(file.size / 1024 / 1024).toFixed(2)} MB)`;
uploadButton.disabled = false;
uploadStatusDiv.style.display = 'none';
progressBar.style.width = '0%';
}
async function handleUpload() {
if (!selectedFile) {
alert('Please select a file first.');
return;
}
const blobName = selectedFile.name;
const blobUrl = `${AZURE_STORAGE_ACCOUNT_URL}/${CONTAINER_NAME}/${blobName}${SAS_TOKEN}`;
statusMessage.textContent = `Uploading ${blobName}...`;
uploadStatusDiv.style.display = 'flex';
uploadStatusDiv.className = 'upload-status'; // Reset classes
progressBar.style.width = '0%';
uploadButton.disabled = true;
try {
const response = await fetch(blobUrl, {
method: 'PUT',
headers: {
'Content-Type': selectedFile.type || 'application/octet-stream',
'x-ms-blob-type': 'BlockBlob'
},
body: selectedFile
});
if (response.ok) {
statusMessage.textContent = 'Upload successful!';
uploadStatusDiv.classList.add('success');
progressBar.style.width = '100%';
} else {
const errorText = await response.text();
statusMessage.textContent = `Upload failed: ${response.status} ${response.statusText}`;
console.error('Azure Blob Upload Error:', errorText);
uploadStatusDiv.classList.add('error');
}
} catch (error) {
statusMessage.textContent = 'An error occurred during upload.';
console.error('Network or Fetch Error:', error);
uploadStatusDiv.classList.add('error');
} finally {
uploadButton.disabled = false; // Re-enable button after completion or error
// Optionally clear selected file or reset UI after a delay
// setTimeout(() => {
// selectedFile = null;
// const fileNameLabel = dropArea.querySelector('label');
// fileNameLabel.textContent = 'Drag and drop a file here, or click to select a file';
// uploadButton.disabled = true;
// uploadStatusDiv.style.display = 'none';
// }, 5000);
}
}
// Initial setup
uploadStatusDiv.style.display = 'none'; // Hide status initially
This direct HTML/JavaScript upload method provides a simple yet powerful way to integrate file uploads with Azure Blob Storage. For more complex scenarios, explore the Azure SDKs for JavaScript.