So che questo è un vecchio post, ma è ancora molto pertinente. Ho scoperto che i browser moderni supportano rfc5987, che consente la codifica utf-8, codificata in percentuale (codifica url). Quindi Naïve file.txt diventa:
Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt
Safari (5) non supporta questo. Invece dovresti usare lo standard Safari per scrivere il nome del file direttamente nell'intestazione codificata utf-8:
Content-Disposition: attachment; filename=Naïve file.txt
IE8 e precedenti non lo supportano e devi usare lo standard IE di codifica utf-8, codificato in percentuale:
Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt
In ASP.Net utilizzo il seguente codice:
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);
Ho testato quanto sopra usando IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5.
Aggiornamento novembre 2013:
Ecco il codice che attualmente uso. Devo ancora supportare IE8, quindi non posso liberarmi della prima parte. Si scopre che i browser su Android utilizzano il download manager Android integrato e non possono analizzare in modo affidabile i nomi dei file in modo standard.
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);
Quanto sopra ora testato in IE7-11, Chrome 32, Opera 12, FF25, Safari 6, usando questo nome file per il download: 你好 abcABCæøåÆØÅäöüïëëîâéíáóúýñ½§! # ¤% & () = `@ £ $ € {[]} + ´¨ ^ ~ '-_,;. txt
Su IE7 funziona per alcuni personaggi ma non per tutti. Ma a chi importa di IE7 al giorno d'oggi?
Questa è la funzione che utilizzo per generare nomi di file sicuri per Android. Nota che non so quali personaggi sono supportati su Android ma ho testato che questi funzionano sicuramente:
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: ho testato in IE7 e IE8 e si è scoperto che non avevo bisogno di sfuggire all'apostrofo ('). Hai un esempio di dove fallisce?
@Dave Van den Eynde: Combinando i due nomi di file su una riga secondo RFC6266 funziona tranne Android e IE7 + 8 e ho aggiornato il codice per riflettere questo. Grazie per il suggerimento
@Thilo: nessuna idea di GoodReader o di qualsiasi altro non browser. Potresti avere un po 'di fortuna usando l'approccio Android.
@Alex Zhukovskiy: non so perché, ma come discusso su Connect non sembra funzionare molto bene.