Home > front end >  How to create HTML links to download links using Azure Blobs
How to create HTML links to download links using Azure Blobs

Time:04-09

I am creating a website using Azure Blobs to store content. The website provides Search and Indexing.

When this link is relative,

<a download="" href="./media5/yyy.png">Download</a>

the browser kicks off a "download".

enter image description here

When the files are stored in Blobs, the users get a link like:

<a download="" href="https://xxx.blob.core.windows.net/media5/yyy.png">Download</a>

However, this navigates to the image.

I need the browser "download" to work.

I have tries setting the Storage Account's CORS Blade: enter image description here

But this did not do anything.

CodePudding user response:

CORS is not going to help in this case. If you want to force download the blob, please change the blob's content-type property to application/octet-stream (or application/binary).

However, please note that when you change the blob's content type to application/octet-stream, it will always be downloaded. You will not be able to display the blob in the browser.

CodePudding user response:

Manrti is correct CORS is not in play. I deleted the Storage Account's CORS Blade.

The fix is 3 parts: 1: Set ContentDispoistion header to "attached"

   var blockBlobClient = new BlockBlobClient(connectionString, container, fileInfo.Name, clientOptions);

        var uploadOptions = new BlobUploadOptions();
        uploadOptions.HttpHeaders = new BlobHttpHeaders();

        switch (fileInfo.Extension)
        {
            case ".wav":
                uploadOptions.HttpHeaders.ContentType = "audio/wav";
                break;
            case ".mp3":
                uploadOptions.HttpHeaders.ContentType = "audio/mpeg";
                break;
            case ".mp4":
                uploadOptions.HttpHeaders.ContentType = "video/mp4";
                break;
            case ".jpg":
                uploadOptions.HttpHeaders.ContentType = "image/jpeg";
                break;
            case ".png":
                uploadOptions.HttpHeaders.ContentType = "image/png";
                break;
            case ".zip":
                uploadOptions.HttpHeaders.ContentType = "application/x-zip-compressed";
                break;
            case ".html":
                uploadOptions.HttpHeaders.ContentType = "text/plain";
                break;
            case ".pdf":
                uploadOptions.HttpHeaders.ContentType = "application/pdf";
                break;
            default:
                break;
        }

        uploadOptions.HttpHeaders.ContentDisposition = "attached";
        uploadOptions.ProgressHandler = progressHandler;

        var contentMD5 = await GetContentMD5(blockBlobClient);
        var contentType = await GetContentType(blockBlobClient);

        using (var fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            if ((sourceMD5 != contentMD5) | (contentType != uploadOptions.HttpHeaders.ContentType))
            {
                Console.WriteLine("\t\tUploading Blob...");
                await blockBlobClient.UploadAsync(fs, uploadOptions);
                contentMD5 = await GetContentMD5(blockBlobClient);
                if (sourceMD5 != contentMD5)
                {
                    throw new Exception($"Uploaded blob ContentMD5[{contentMD5}] does not match SourceMD5Hash[{sourceMD5}] for {blockBlobClient.Name}");
                }
            }
            return blockBlobClient;
        }

2: You must use a SAS Url to have the Content-Disposition header be returned:

var uri = blobClient.GenerateSasUri(BlobSasPermissions.Read, new DateTimeOffset(DateTime.UtcNow.AddYears(2)));

3: HTML Link:

<a download="" href="https://xxx.blob.core.windows.net/media5/yyy.png?sv=2020-08-04&se=2024-04-08T14:43:28Z&sr=b&sp=r&sig=ZWdbpd8y2hr02MpzgxDC/u2eqi5HukIYhXnLiYK4Rrk=">Download</a>
  • Related