Ich weiß, dass dies ein alter Beitrag ist, aber er ist immer noch sehr relevant. Ich habe festgestellt, dass moderne Browser rfc5987 unterstützen, was eine utf-8-Codierung in Prozent (url-codiert) ermöglicht. Dann wird Naive Datei.txt:
Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt
Safari (5) unterstützt dies nicht. Stattdessen sollten Sie den Safari-Standard verwenden, um den Dateinamen direkt in Ihren utf-8-codierten Header zu schreiben:
Content-Disposition: attachment; filename=Naïve file.txt
IE8 und älter unterstützen es ebenfalls nicht und Sie müssen den IE-Standard der utf-8-Codierung verwenden, prozentual codiert:
Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt
In ASP.Net verwende ich den folgenden Code:
string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.Browser.Browser == "Safari")
contentDisposition = "attachment; filename=" + fileName;
else
contentDisposition = "attachment; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);
Ich habe das oben genannte mit IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5 getestet.
Update November 2013:
Hier ist der Code, den ich derzeit verwende. Ich muss IE8 noch unterstützen, damit ich den ersten Teil nicht loswerden kann. Es stellt sich heraus, dass Browser unter Android den integrierten Android-Download-Manager verwenden und Dateinamen nicht auf die übliche Weise zuverlässig analysieren können.
string contentDisposition;
if (Request.Browser.Browser == "IE" && (Request.Browser.Version == "7.0" || Request.Browser.Version == "8.0"))
contentDisposition = "attachment; filename=" + Uri.EscapeDataString(fileName);
else if (Request.UserAgent != null && Request.UserAgent.ToLowerInvariant().Contains("android")) // android built-in download manager (all browsers on android)
contentDisposition = "attachment; filename=\"" + MakeAndroidSafeFileName(fileName) + "\"";
else
contentDisposition = "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + Uri.EscapeDataString(fileName);
Response.AddHeader("Content-Disposition", contentDisposition);
Die oben genannten Tests wurden jetzt in IE7-11, Chrome 32, Opera 12, FF25, Safari 6 unter Verwendung dieses Dateinamens zum Herunterladen getestet: 你好 abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§! # ¤% & () = `@ £ $ € {[]} + ´¨ ^ ~ '-_,;. txt
Auf IE7 funktioniert es für einige Zeichen, aber nicht für alle. Aber wen interessiert IE7 heutzutage?
Dies ist die Funktion, mit der ich sichere Dateinamen für Android generiere. Beachten Sie, dass ich nicht weiß, welche Zeichen unter Android unterstützt werden, aber dass ich getestet habe, dass diese sicher funktionieren:
private static readonly Dictionary<char, char> AndroidAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-+,@£$€!½§~'=()[]{}0123456789".ToDictionary(c => c);
private string MakeAndroidSafeFileName(string fileName)
{
char[] newFileName = fileName.ToCharArray();
for (int i = 0; i < newFileName.Length; i++)
{
if (!AndroidAllowedChars.ContainsKey(newFileName[i]))
newFileName[i] = '_';
}
return new string(newFileName);
}
@ TomZ: Ich habe in IE7 und IE8 getestet und es stellte sich heraus, dass ich nicht dem Apostroph (') entkommen musste. Haben Sie ein Beispiel, wo es fehlschlägt?
@ Dave Van den Eynde: Das Kombinieren der beiden Dateinamen in einer Zeile gemäß RFC6266 funktioniert mit Ausnahme von Android und IE7 + 8, und ich habe den Code aktualisiert, um dies widerzuspiegeln. Vielen Dank für den Vorschlag.
@Thilo: Keine Ahnung von GoodReader oder einem anderen Nicht-Browser. Mit dem Android-Ansatz haben Sie möglicherweise etwas Glück.
@ Alex Zhukovskiy: Ich weiß nicht warum, aber wie auf Connect besprochen , scheint es nicht besonders gut zu funktionieren.