简体   繁体   中英

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?

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM