ฉันรู้ว่านี่เป็นโพสต์เก่า แต่ก็ยังมีความเกี่ยวข้องมาก ฉันพบว่าเบราว์เซอร์ที่ทันสมัยรองรับ 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
อัปเดตพฤศจิกายน 2556:
นี่คือรหัสที่ฉันใช้ในปัจจุบัน ฉันยังต้องรองรับ 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 โดยใช้ชื่อไฟล์สำหรับดาวน์โหลด: ^ ~ '-_;. 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 และปรากฎว่าฉันไม่จำเป็นต้องหลบหนี apostrophe (') คุณมีตัวอย่างที่ล้มเหลวหรือไม่?
@Dave Van den Eynde: การรวมชื่อไฟล์ทั้งสองเข้าด้วยกันในบรรทัดเดียวตาม RFC6266 ทำงานได้ยกเว้นสำหรับ Android และ IE7 + 8 และฉันได้อัปเดตรหัสเพื่อแสดงถึงสิ่งนี้ ขอบคุณสำหรับคำแนะนำ
@Thilo: ไม่มีความคิดเกี่ยวกับ GoodReader หรืออื่น ๆ ที่ไม่ใช่เบราว์เซอร์ คุณอาจมีโชคโดยใช้วิธีการของ Android
@Alex Zhukovskiy: ฉันไม่รู้ว่าทำไม แต่ตามที่กล่าวไว้ในการเชื่อมต่อดูเหมือนว่าจะทำงานได้ไม่ดีนัก