导航到 url 时始终下载 Azure Blob

Posted

技术标签:

【中文标题】导航到 url 时始终下载 Azure Blob【英文标题】:Azure Blob always downloads when navigating to url 【发布时间】:2012-08-02 02:32:02 【问题描述】:

在我们的应用程序中,我们让用户能够将文档上传到 Windows azure blob 存储帐户。上传文档或图像后,它会被分配一些 url (https://name.blob.core.windows.net/container/file-name.jpg)。如果文档是可以由浏览器呈现的图像或 pdf 或某些文件,我们会尝试在浏览器中显示它,而不需要用户下载文件。如果我们只是打开一个新窗口或选项卡并将用户定向到 IE 中的 blob uri,则图像或 pdf 在浏览器中正确呈现。但是,如果我们尝试在 Chrome、FireFox 或 Safari 中打开一个指向 uri 的新窗口,它只会下载文件而不是在浏览器中显示它。

有没有办法强制后三个浏览器只显示文件而不是下载文件?

【问题讨论】:

【参考方案1】:

这是因为您没有设置 blob 的 content type 属性(默认为 application/octet-stream,在大多数浏览器中会触发下载)。如果您希望 PDF 文件正确显示,您需要将 PDF 文件的内容类型更改为 application/pdf(jpeg 文件为 image/jpeg)。

您可以使用 Azure Storage Explorer、Cloud Storage Studio、CloudBerry、CloudXplorer 等常用工具或使用 SDK 更改内容类型。请注意,其中一些工具会在上传文件后自动将内容类型设置为正确的类型。

【讨论】:

网址不再有效【参考方案2】:
   blob.Properties.ContentType = "application/pdf";

//通过扩展名获取文件的内容类型

    public static string GetFileContentType(string FilePath)
    
        string ContentType = String.Empty;
        string Extension = Path.GetExtension(FilePath).ToLower();

        switch (Extension)
        
            case ConstantUtility.FILE_EXTENSION_PDF:
                ContentType = "application/pdf";
                break;
            case ConstantUtility.FILE_EXTENSION_TXT:
                ContentType = "text/plain";
                break;
            case ConstantUtility.FILE_EXTENSION_BMP:
                ContentType = "image/bmp";
                break;
            case ConstantUtility.FILE_EXTENSION_GIF:
                ContentType = "image/gif";
                break;
            case ConstantUtility.FILE_EXTENSION_PNG:
                ContentType = "image/png";
                break;
            case ConstantUtility.FILE_EXTENSION_JPG:
                ContentType = "image/jpeg";
                break;
            case ConstantUtility.FILE_EXTENSION_JPEG:
                ContentType = "image/jpeg";
                break;
            case ConstantUtility.FILE_EXTENSION_XLS:
                ContentType = "application/vnd.ms-excel";
                break;
            case ConstantUtility.FILE_EXTENSION_XLSX:
                ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                break;
            case ConstantUtility.FILE_EXTENSION_CSV:
                ContentType = "text/csv";
                break;
            case ConstantUtility.FILE_EXTENSION_html:
                ContentType = "text/html";
                break;
            case ConstantUtility.FILE_EXTENSION_XML:
                ContentType = "text/xml";
                break;
            case ConstantUtility.FILE_EXTENSION_ZIP:
                ContentType = "application/zip";
                break;
            default:
                ContentType = "application/octet-stream";
                break;

        


        return ContentType;
    

在保存时使用它来设置 blob 的内容类型。

Set Content-type of media files stored on Blob

【讨论】:

如果您使用 HttpPostedFileBase,它已经包含内容类型 attr ex:blockBlob.Properties.ContentType = httpPostedFileBase.ContentType; 效果很好;我最终决定自动确定我的文件的 mime 类型:blob.Properties.ContentType = MimeMapping.GetMimeMapping(path);【参考方案3】:

对于通过 PowerShell 上传文件的用户,请使用以下语法在上传期间设置内容类型。

Set-AzureStorageBlobContent -File <localFilePath> -Container <containerName> -Properties @"ContentType"="text/plain" -Context $ctx

上面我将 blob 内容类型设置为 text/plain,这在上传将与模板一起使用的 JSON 和 HTML 文件时很有用。更多内容类型标头值列表here。

【讨论】:

谢谢,这对我有帮助。我只需要将其更改为 -Properties @"ContentType"="text/html" 以使 html 页面可浏览,而不是显示为文本。【参考方案4】:

如果使用 Azure SDK (12.x+),则需要使用传入上传方法的 BlobHttpHeaders(而不是 blob.Properties.ContentType)进行更改。

例如:

    var header = new BlobHttpHeaders();
    header.ContentType = "image/jpeg";

    var response = await blobClient.UploadAsync(stream, header);

【讨论】:

【参考方案5】:
public String sasURL(String filePath) throws URISyntaxException, StorageException, InvalidKeyException 
    CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(filePath);
    SharedAccessBlobPolicy sasPolicy = new SharedAccessBlobPolicy();
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.add(Calendar.HOUR, 3);
    sasPolicy.setSharedAccessExpiryTime(calendar.getTime());
    sasPolicy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.LIST));
    SharedAccessBlobHeaders sharedAccessBlobHeaders = new SharedAccessBlobHeaders();
    sharedAccessBlobHeaders.setContentType(MediaType.APPLICATION_PDF_VALUE);
    String sas = cloudBlockBlob.generateSharedAccessSignature(sasPolicy, sharedAccessBlobHeaders,null);
    return cloudBlockBlob.getUri()+"?"+sas;

【讨论】:

一个好的答案将始终包括解释为什么这会解决问题,以便 OP 和任何未来的读者可以从中学习。

以上是关于导航到 url 时始终下载 Azure Blob的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Azure blob 文件下载到下载文件夹中,而不是在浏览器中

通过直接 URL 浏览时上传到 Azure Blob 存储的图像不可用

如何通过 URL 下载 Azure BLOB 存储文件

将文件上传到 Azure Blob 存储导致大小为 0

天蓝色 blob 存储中的 XLSX 文件作为 zip 文件下载

从 Url 将 .vhd 作为 Page-Blob 上传到 azure-blob-storage