Ich weiß, dies ist ein alter Beitrag, aber er ist immer noch sehr aktuell. Ich habe festgestellt, dass moderne Browser rfc5987 unterstützen, was eine utf-8-Kodierung erlaubt, und zwar prozentual kodiert (url-encoded). Dann Naïve file.txt wird:
Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt
Safari (5) unterstützt dies nicht. Stattdessen sollten Sie den Safari-Standard verwenden und den Dateinamen direkt in Ihren utf-8-kodierten Header schreiben:
Content-Disposition: attachment; filename=Naïve file.txt
IE8 und ältere Versionen unterstützen dies ebenfalls nicht, und Sie müssen den IE-Standard der utf-8-Kodierung verwenden, d. h. prozentual kodiert:
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 und Safari 5 getestet.
Update November 2013:
Hier ist der Code, den ich derzeit verwende. Ich muss immer noch den IE8 unterstützen, also kann ich den ersten Teil nicht loswerden. Es hat sich herausgestellt, dass Browser auf Android den eingebauten Android-Download-Manager verwenden und dieser kann Dateinamen nicht zuverlässig auf die übliche Art und Weise parsen.
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);
Das oben genannte wurde jetzt in IE7-11, Chrome 32, Opera 12, FF25, Safari 6 getestet, wobei dieser Dateiname zum Download verwendet wurde: abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§!#¤%&()=`@£$€{[]}+'¨^~'-_,;.txt
Im IE7 funktioniert es bei einigen Zeichen, aber nicht bei allen. Aber wer kümmert sich heutzutage noch um den IE7?
Dies ist die Funktion, die ich verwende, um sichere Dateinamen für Android zu generieren. Beachten Sie, dass ich nicht weiß, welche Zeichen auf 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 es im IE7 und IE8 getestet, und es stellte sich heraus, dass ich das Hochkomma (') nicht ausblenden musste. Haben Sie ein Beispiel, bei dem es nicht funktioniert?
@Dave Van den Eynde: Die Kombination der beiden Dateinamen in einer Zeile gemäß RFC6266 funktioniert, außer bei Android und IE7+8, und ich habe den Code aktualisiert, um dies zu berücksichtigen. Vielen Dank für die Anregung.
@Thilo: Keine Ahnung von GoodReader oder anderen Nicht-Browsern. Vielleicht haben Sie Glück, wenn Sie den Android-Ansatz verwenden.
@Alex Zhukovskiy: Ich weiß nicht, warum, aber wie auf Verbinden Sie es scheint nicht besonders gut zu funktionieren.
0 Stimmen
Es funktioniert für Mobile Safari (raw utf-8 wie von @Martin Ørding-Thomsen vorgeschlagen), aber das funktioniert nicht für GoodReader vom gleichen Gerät. Irgendwelche Ideen?
0 Stimmen
Siehe auch diese ähnliche Frage
1 Stimmen
Kornel's Antwort hat sich als der Weg des geringsten Widerstands erwiesen, wenn man das letzte Segment des Weges festlegen kann; gekoppelt ist dies mit
Content-Disposition: attachment
.