Direct-to-Azure Blob

Browser-direct Azure Blob upload

The browser uploads each block via PutBlock against a pre-signed blob SAS URL, then finalises with a single PutBlockList. Mirrors the S3 pattern - your server signs once and the bytes bypass IIS entirely. IndexedDB resume preserves the upload session + already-committed block IDs so reloads pick up where they stopped.

Client config
AjaxUploader.create('#uploader', {
 uploadUrl: '/ajaxupload.axd/upload',
 strategy: 'azure',
 chunkSize: 4 * 1024 * 1024, // Azure block size chunkConcurrency: 4,
 persistState: true,
 persistAdapter: 'indexeddb'
});
Server-side (Global.asax.cs)
using AjaxUploader.Providers;

protected void Application_Start(object sender, EventArgs e)
{
 // Your IAzureSigner wraps BlobServiceClient and hands out SAS URLs. Azure.Signer = new MyAzureSigner(
 connectionString: ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString,
 containerName: "uploads");
}
Wire protocol
  • POST /ajaxupload.axd/azure/create -> { uploadId, blobUrl, blockIdPrefix }
  • PUT {blobUrl}&comp=block&blockid=... per block (browser-direct)
  • PUT {blobUrl}&comp=blocklist with XML BlockList body (browser-direct)
  • POST /ajaxupload.axd/azure/complete to record metadata server-side
Container CORS
az storage cors add \
 --methods PUT \
 --origins https://ajaxuploader.com \
 --allowed-headers "*" \
 --exposed-headers "*" \
 --services b \
 --max-age 3600