Я знаю, что это старый пост, но он все еще очень актуален. Я обнаружил, что современные браузеры поддерживают rfc5987, который допускает кодировку utf-8 с процентной кодировкой (с кодировкой url). Тогда Naïve file.txt станет:
Content-Disposition: attachment; filename*=UTF-8''Na%C3%AFve%20file.txt
Safari (5) не поддерживает это. Вместо этого вы должны использовать стандарт Safari для записи имени файла непосредственно в заголовок в кодировке utf-8:
Content-Disposition: attachment; filename=Naïve file.txt
IE8 и более ранние версии также не поддерживают его, и вам нужно использовать стандарт IE кодировки utf-8 с процентной кодировкой:
Content-Disposition: attachment; filename=Na%C3%AFve%20file.txt
В ASP.Net я использую следующий код:
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);
Я тестировал вышеуказанное, используя IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5.
Обновление, ноябрь 2013 г .:
Вот код, который я использую сейчас. Мне все еще нужно поддерживать IE8, поэтому я не могу избавиться от первой части. Оказывается, браузеры на Android используют встроенный диспетчер загрузок Android, и он не может надежно анализировать имена файлов стандартным способом.
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);
Вышеупомянутое теперь протестировано в IE7-11, Chrome 32, Opera 12, FF25, Safari 6 с использованием этого файла для загрузки: 你好 abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§! # ¤% & () = `@ £ $ € {[]} + ´¨ ^ ~ '-_,;. txt
В IE7 это работает для некоторых символов, но не для всех. Но кого сейчас волнует IE7?
Это функция, которую я использую для создания безопасных имен файлов для Android. Обратите внимание, что я не знаю, какие символы поддерживаются на Android, но я проверил, что они работают точно:
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: Я тестировал IE7 и IE8, и оказалось, что мне не нужно избегать апострофа ('). У вас есть пример, когда это не удается?
@Dave Van den Eynde: объединение двух имен файлов в одной строке, как в соответствии с RFC6266, работает за исключением Android и IE7 + 8, и я обновил код, чтобы отразить это. Спасибо за предложение.
@Thilo: Не знаю ни о GoodReader, ни о каком-либо другом небраузере. Возможно, вам повезет с использованием подхода Android.
@ Алексей Жуковский: я не знаю почему, но как обсуждалось на Подключить, похоже, не очень хорошо работает.
person
Martin Ørding-Thomsen
schedule
19.07.2011
Content-Disposition: attachment
. - person Antti Haapala   schedule 12.09.2016