Christo S. Christov
Christo S. Christov

Reputation: 2309

How to download file with filename?

I've been banging my head for a few weeks on a problem.

I provide a download url to the client in order to download content from the storage. Here's how I do that:

  var sasConstraints = new SharedAccessBlobPolicy();
  sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
  sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
  sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
  var sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);

This way I generate a link to the Azure storage blob.

Now I send this link to the client and open it as :

  let a = document.createElement('a');
  a.download = data.fileName;
  a.href = data.url
  a.click()
  document.removeChild(a)

But it still doesn't download the file with the correct file name ( it downloads it as the GUID of the blob). This happens because the azure storage overrides with headers the name i specified in the download attribute. How do I get the correct file name to be delivered? Should I try to disable the headers of the Azure storage? Should I change the code on the client?

Upvotes: 0

Views: 1482

Answers (2)

Gaurav Mantri
Gaurav Mantri

Reputation: 136366

Assuming you have a blob called abc.png and you want it to be downloaded as def.png, what you could do is overwrite Content-Disposition header in your SAS token. Then when the user clicks on the download link, the file will be saved as def.png by default.

Please see the sample code below:

    private static void OverrideContentDispositionHeaderInSharedAccessSignature()
    {
        var cred = new StorageCredentials(accountName, accountKey);
        var account = new CloudStorageAccount(cred, true);
        var blobClient = account.CreateCloudBlobClient();
        var container = blobClient.GetContainerReference("container-name");
        var blob = container.GetBlockBlobReference("abc.png");
        var sasConstraints = new SharedAccessBlobPolicy();
        sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
        sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
        sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
        var sasBlobHeaders = new SharedAccessBlobHeaders()
        {
            ContentDisposition = "attachment; filename=\"def.png\""
        };
        var sasBlobToken = blob.GetSharedAccessSignature(sasConstraints, sasBlobHeaders);
        var sasUrl = blob.Uri.AbsoluteUri + sasBlobToken;
    }

With this you don't need to set the download attribute on your link element. Your client side code would be much simple. Something like:

        let a = document.createElement('a');
        a.href = data.url
        a.click()
        document.removeChild(a)

Upvotes: 3

guest271314
guest271314

Reputation: 1

You cannot force a client to download a file having a specific file name. The client can change the name of the file at either the Save File dialog or when the file is saved at local filesystem.

Upvotes: 0

Related Questions