2013-08-22 80 views
8

我們使用這個代碼來生成請求,並設置文件名進行下載:如何在S3的response-content-disposition頭中使用unicode字符?

var request = new GetPreSignedUrlRequest() 
    .WithBucketName(S3BucketName) 
    .WithExpires(requestExpirationTime) 
    .WithKey(file.S3Key) 
    .WithResponseHeaderOverrides(
     new ResponseHeaderOverrides() 
      .WithContentDisposition("attachment; filename=\"Unicode FileName ᗩ Test.txt\"")); 

這會產生以下鏈接:

/s3path?AWSAccessKeyId=xxxx&Expires=1377199946&response-content-disposition=attachment%3B%20filename%3D"Unicode%20FileName%20ᗩ%20Test.txt"&Signature=xxxxx 

其中給出這個錯誤:

<Error> 
    <Code>InvalidArgument</Code> 
    <Message> 
     Header value cannot be represented using ISO-8859-1. 
    </Message> 
    <ArgumentValue>attachment; filename="Unicode ᗩ filename.txt"</ArgumentValue> 
    <ArgumentName>response-content-disposition</ArgumentName> 
    <RequestId>368BD60502854514</RequestId> 
    <HostId> 
     BiUUYp4d9iXfK68jKVxWZEp25m5je166M0ZY1VmoPk9pN9A69HLHcff6WIVLWk1B 
    </HostId> 
</Error> 

我們如何在response-content-disposition頭中使用非ISO-8859-1字符,如unicode?

+0

AWS論壇主題:https://forums.aws.amazon.com/thread.jspa?threadID=133257 –

回答

4

this StackOverflow answer所述,在Content-Disposition中沒有可互操作的方式對非ASCII名稱進行編碼。瀏覽器兼容性一團糟。

我們最終這樣做的方式是,在所有瀏覽器中都能正常工作,用' - '取代所有非ISO-8859-1字符。下面的代碼:

private static readonly Encoding ContentDispositionHeaderEncoding = Encoding.GetEncoding("ISO-8859-1"); 

public static string GetWebSafeFileName(string fileName) 
{ 
    // We need to convert the file name to ISO-8859-1 due to browser compatibility problems with the Content-Disposition Header (see: https://stackoverflow.com/a/216777/1038611) 
    var webSafeFileName = Encoding.Convert(Encoding.Unicode, ContentDispositionHeaderEncoding, Encoding.Unicode.GetBytes(fileName)); 

    // Furthermore, any characters not supported by ISO-8859-1 will be replaced by « ? », which is not an acceptable file name character. So we replace these as well. 
    return ContentDispositionHeaderEncoding.GetString(webSafeFileName).Replace('?', '-'); 
} 

繼亞歷克斯Couper的答案,我發現在.NET的方式通過調用HttpEncoder

調用內部功能的內部方法只編碼非ASCII字符不建議,因爲他們可能在未來版本的框架中更改!此外,如上所述,這不適用於所有瀏覽器。我要離開這裏以防萬一有人需要這樣做。

var type = typeof(System.Web.Util.HttpEncoder); 
var methodInfo = type.GetMethod("UrlEncodeNonAscii", BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(string), typeof(Encoding) }, null); 
object[] parameters = {fileName, Encoding.UTF8}; 

var encoder = new System.Web.Util.HttpEncoder(); 

var encodedFileName = (string) methodInfo.Invoke(encoder, parameters); 
+0

哦,哇,微軟已經完成了這個功能並且隱藏了它!您可以在源CS文件[here](http://referencesource.microsoft。com /#System.Web/xsp/system/Web/Util/HttpEncoder.cs) 如果有人能夠使其在vb.net中工作,那很好!我不知道如何轉換「IntToHex((b >> 4)& 0xf);」部分!(並且在線轉換器不能) – foxontherock

+1

以下是VB.net中的部分:IntToHex((b >> 4)And&Hf) –

5

我有這個問題,我通過正確編碼unicode字符串來解決它。

我在python boto土地:

>>> import urllib 
>>> encoded = urllib.quote('Unicode FileName ᗩ Test.txt') 
>>> print encoded 

"Unicode%20%E1%97%A9%20filename.txt" 

然後,使用該編碼串作爲響應內容-disposition首部值。

在Java中,我相信你可以達到同樣的效果:

URLEncoder.encode(original_string, "UTF-8") 

希望這可以幫助別人在某些時候都重要!

+1

我發現這個功能(在.NET):System.Web.HttpUtility.UrlEncode(文件名,Encoding.UTF8)。問題是它也會用+字符替換空格,並且它還會編碼大多數非字母字符,如',這會使下載的文件名看起來很亂。 我發現了這個工作的完美功能,但它被遺憾地標記爲內部的(在HttpEncoder.cs中),所以它不能直接使用,沒有一些黑客。 //助手只對非ASCII字符的字符進行編碼 internal String UrlEncodeNonAscii(string str,Encoding e) –

相關問題