Saya tahu ini adalah pos lama tetapi masih sangat relevan. Saya telah menemukan bahwa browser modern mendukung rfc5987, yang memungkinkan encoding utf-8, persentase yang disandikan (url-encoded). Kemudian Naïve file.txt menjadi:
Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt
Safari (5) tidak mendukung ini. Sebagai gantinya, Anda harus menggunakan standar Safari untuk menulis nama file secara langsung di header utf-8 Anda yang dikodekan:
Content-Disposition: attachment; filename=Naïve file.txt
IE8 dan yang lebih lama juga tidak mendukungnya dan Anda perlu menggunakan standar IE untuk pengkodean utf-8, persentase yang disandikan:
Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt
Di ASP.Net saya menggunakan kode berikut:
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);
Saya menguji di atas menggunakan IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5.
Pembaruan November 2013:
Berikut adalah kode yang saya gunakan saat ini. Saya masih harus mendukung IE8, jadi saya tidak bisa menghilangkan bagian pertama. Ternyata peramban di Android menggunakan pengelola unduhan bawaan Android dan tidak dapat mengurai nama file dengan cara standar.
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);
Di atas sekarang diuji di IE7-11, Chrome 32, Opera 12, FF25, Safari 6, menggunakan nama file ini untuk diunduh: 你好 abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§! # ¤% & () = `@ £ $ {{]} + ´¨ ^ ~ '-_,;. txt
Pada IE7 berfungsi untuk beberapa karakter tetapi tidak semua. Tapi siapa yang peduli dengan IE7 saat ini?
Ini adalah fungsi yang saya gunakan untuk menghasilkan nama file yang aman untuk Android. Perhatikan bahwa saya tidak tahu karakter mana yang didukung di Android tetapi saya telah menguji apakah ini berfungsi:
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: Saya diuji di IE7 dan IE8 dan ternyata saya tidak perlu melarikan diri tanda kutip ('). Apakah Anda memiliki contoh gagal?
@Dave Van den Eynde: Menggabungkan dua nama file pada satu baris sesuai dengan RFC6266 berfungsi kecuali untuk Android dan IE7 + 8 dan saya telah memperbarui kode untuk mencerminkan ini. Terima kasih atas sarannya.
@Thilo: Tidak tahu tentang GoodReader atau non-browser lainnya. Anda mungkin beruntung menggunakan pendekatan Android.
@Alex Zhukovskiy: Saya tidak tahu mengapa, tetapi seperti yang dibahas di Connect sepertinya tidak berfungsi dengan baik.