当我使用shared access signature (SAS) Token构建网址时,我目前遇到Azure文件存储问题。该文件将在浏览器中下载,但内容类型始终为application / octet-stream,而不是更改为匹配文件的mime类型。如果我将文件放在Azure BLOB存储中并使用SAS令牌构建URL,它会为我的文件(image / jpeg)发送正确的内容类型。
我已将我的存储帐户从V1升级到V2,认为这是问题,但它没有修复它。
有没有人知道我可以尝试使用带有SAS令牌的URL来下载文件时,Azure文件存储可以返回正确的内容类型?
答案 0 :(得分:1)
到目前为止,这些是我发现的内容类型的唯一修复:
对我来说,这些都不是可以接受的选择。如果用户通过门户或Microsoft Azure Storage Explore上传文件并忘记更改内容类型,前两个可能会导致错误。我也不想编写Azure功能或Web作业来监视和修复此问题。
由于blob存储在通过Microsoft Azure Storage Explore上传或通过门户网站上传时不会出现同样的问题,因此成本要低得多,并且都可以使用SAS令牌,我们正在转向blob存储。我们确实失去了将驱动器安装到我们的本地计算机并使用Beyond Compare之类的东西进行文件比较的能力,但这是我们可以忍受的缺点。
如果有人比上面提到的解决这个问题的解决方案有更好的解决方案,我很乐意将其投票。但是,我认为微软必须对此问题进行修改才能修复。
答案 1 :(得分:1)
当我通过门户网站将jpeg文件上传到文件共享时,内容类型确实已更改为application/octet-stream
。但我无法重现您的下载问题。
我没有在我的SAS请求uri中指定内容类型,但该文件只是作为jpeg文件下载。已经在SDK(帐户SAS /存储访问策略/ SAS文件本身)或REST API中进行了测试,即使没有内容类型也都可以使用。
您可以尝试使用以下代码指定内容类型。
SharedAccessFileHeaders header = new SharedAccessFileHeaders()
{
ContentDisposition = "attachment",
ContentType = "image/jpeg"
};
string sasToken = file.GetSharedAccessSignature(sharedPolicy,header);
答案 2 :(得分:0)
如果未提供任何内容,则Azure Blob会降至“ application / octet-stream”的默认值。为了获得正确的模仿类型,这是我对烧瓶应用程序所做的:
func imageIsEmpty(_ image: UIImage) -> Bool {
guard let cgImage = image.cgImage,
let dataProvider = cgImage.dataProvider else
{
return true
}
let pixelData = dataProvider.data
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let imageWidth = Int(image.size.width)
let imageHeight = Int(image.size.height)
for x in 0..<imageWidth {
for y in 0..<imageHeight {
let pixelIndex = ((imageWidth * y) + x) * 4
let r = data[pixelIndex]
let g = data[pixelIndex + 1]
let b = data[pixelIndex + 2]
let a = data[pixelIndex + 3]
if a != 0 {
if r != 0 || g != 0 || b != 0 {
return false
}
}
}
}
return true
}
mime_type已传递到ContentSettings,以获取上传到天蓝色blob的文件的当前mimetypes。
答案 3 :(得分:0)
// here you define your file content type
CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference(file.FileName);
cloudBlockBlob.Properties.ContentType = file.ContentType; //content type
答案 4 :(得分:0)
这与使用com.microsoft.azure azure-storage库的Java一起使用。正在上传到共享访问签名资源。
InputStream is = new FileInputStream(file);
CloudBlockBlob cloudBlockBlob = new CloudBlockBlob(new URI(sasUri));
cloudBlockBlob.getProperties().setContentType("application/pdf");
cloudBlockBlob.upload(is, file.length());
is.close();
答案 5 :(得分:0)
对于希望使用声明的内容类型正确上传文件的任何人,v12 客户端已更改设置内容类型。您可以使用 file.Create
ShareFileClient file = directory.GetFileClient(fileName);
using FileStream stream = File.OpenRead(@"C:\Temp\Amanita_muscaria.jpg");
file.Create(stream.Length, new ShareFileHttpHeaders { ContentType = ContentType(fileName) });
file.UploadRange(new HttpRange(0, stream.Length),stream);
其中 ContentType(fileName)
是对文件名的评估,例如:
if (fileName.EndsWith(".txt")) return "text/plain";
// etc
答案 6 :(得分:0)
我知道我不是在回答这个问题,但我相信答案是适用的。我的存储帐户遇到了同样的问题,我需要将其作为静态网站使用。每当我将 blob 上传到容器时,默认类型是“application/octet-stream”,因此 index.html 会被下载而不是被显示。
要更改文件类型,请执行以下操作:
# Get Storage Account for its context
$storageAccount = Get-AzStorageAccount -ResourceGroupName <Resource Group Name> -Name <Storage Account Name>
# Get Blobs inside container of storage account
$blobs = Get-AzStorageBlob -Context $storageAccount.Context -Container <Container Name>
foreach ($blob in $blobs) {
$CloudBlockBlob = [Microsoft.Azure.Storage.Blob.CloudBlockBlob] $blob.ICloudBlob
$CloudBlockBlob.Properties.ContentType = <Desired type as string>
$CloudBlockBlob.SetProperties()
}
注意:对于 Azure 文件存储,您可能希望将库更改为 [Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob]