Uploading to Azure Blob Storage with HTML

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:

Steps to Upload

1

Generate a SAS Token

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.

2

HTML File Input and Upload Form

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>
            
3

JavaScript for Upload Logic

The JavaScript code will:

  • Listen for file selection.
  • Construct the full Azure Blob URL using the storage endpoint, container name, and blob name (filename).
  • Construct the full URL for the PUT request including the SAS token.
  • Send a PUT request to Azure Blob Storage using the Fetch API.
  • Handle upload progress and status updates.

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
                    

Important Considerations

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.