【问题标题】:Azure Blob always downloads when navigating to url导航到 url 时始终下载 Azure Blob
【发布时间】: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 的新窗口,它只会下载文件而不是在浏览器中显示它。

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

【问题讨论】:

    标签: firefox google-chrome azure blob azure-storage


    【解决方案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 和任何未来的读者可以从中学习。
      猜你喜欢
      • 2021-10-29
      • 2016-09-19
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2014-05-10
      相关资源
      最近更新 更多