用“;”下载文件或文件名中的“#”废墟文件名

时间:2009-03-29 20:52:07

标签: asp.net

我有一个名为AttachmentDownload.aspx的文件,里面的Page_Load方法有这样的代码提供下载文件。所有名称在IE中都能正常工作,但名称中包含“;”要么 ”#”。它们为用户提供了名为“AttachmentDownload.aspx”的文件保存。这有解决方法吗?

以下是一个例子:

var fileName = Server.UrlPathEncode (";%.txt");
Response.AddHeader("content-disposition", String.Format("attachment;filename=\"{0}\"", fileName));
Response.WriteFile(path);
Response.End();

4 个答案:

答案 0 :(得分:8)

  

所有名称在IE中都能正常工作,但名称中包含“;”或“#”。

我不能用'#'重现问题但是';'肯定会打破它。就像'''和'\'一样(你可以在Unix上的文件名中使用它,这将破坏你的引用字符串)。

RFC1521中定义了在RFC822系列参数化标头中包含带外字符的“正确”解决方案,如RFC2822:不应包含在“令牌”中的字符串应该被包装在带引号的字符串中,RFC2231定义为“和\字符反斜杠转义,然后用引号括起来。

然后

http://www.example.com/AttachmentDownload.aspx/Foo%23Bar以一种非常复杂的方式扩展它,在头参数中包含非ASCII字符,理论上你可以使用它来支持Unicode字符。

实际上:HTTP实际上并不是RFC822系列规范,并且这些东西都不适用于常规浏览器(除了Opera中的反斜杠转义)。没有可靠的方法来获取客户端的Unicode Content-Disposition文件名,而你的';'问题不是因为任何转义问题,而是因为IE无法解析太妃糖的参数化标题(它分裂了字符串中的下一个分号,即使它被引号括起来。)

对于可靠的跨浏览器文件名设置,您可以在现实世界中采用两种方法:

  1. 在将文件名放入Content-Disposition标头之前,从文件名中删除任何令人反感的内容。这包括前导/尾随空格/点,大多数其他标点符号和任何非ASCII。

  2. 根本不要在Content-Disposition标头中指定文件名,让浏览器在URL的最后部分计算出要使用的文件名。要阻止它选择“AttachmentDownload.aspx”,您可以将任何您喜欢的内容作为尾随URL部分,例如:

    {{3}}

  3. 这要求您使用普通URL编码和UTF-8的Unicode字符编码大多数标点符号,但至少可以获取字符。上面的结果是'Foo; Bar'的文件下载提示。

    请注意,即使您可以对像这样的URL路径部分中的“不喜欢”的Windows不友好的字符进行编码,对于下载的文件,最好不要这样做,因为IE会通过尝试保存来响应该文件在文件名中使用'\ n'',并且会无声地神秘地响应。

答案 1 :(得分:3)

我开始只清理所有特殊字符的文件名。我想出了一个映射表,它应该映射大多数常用的字符。

//http://www.pjb.com.au/comp/diacritics.html
private static string[,] CharacterReplacements = { 
    { " ", "-"},
    { "&", "-"},
    { "?", "-"},
    { "!", "-"},
    { "%", "-"},
    { "+", "-"},
    { "#", "-"},
    { ":", "-"},
    { ";", "-"},
    { ".", "-"},

    { "¢", "c" },   //cent
    { "£", "P" },   //Pound
    { "€", "E" },   //Euro
    { "¥", "Y" },   //Yen
    { "°", "d" },   //degree
    { "¼", "1-4" }, //fraction one-quarter
    { "½", "1-2" }, //fraction half    
    { "¾", "1-3" }, //fraction three-quarters}
    { "@", "AT)"}, //at                                                  
    { "Œ", "OE" },  //OE ligature, French (in ISO-8859-15)        
    { "œ", "oe" },  //OE ligature, French (in ISO-8859-15)        

    {"Å","A" },  //ring
    {"Æ","AE"},  //diphthong
    {"Ç","C" },  //cedilla
    {"È","E" },  //grave accent
    {"É","E" },  //acute accent
    {"Ê","E" },  //circumflex accent
    {"Ë","E" },  //umlaut mark
    {"Ì","I" },  //grave accent
    {"Í","I" },  //acute accent
    {"Î","I" },  //circumflex accent
    {"Ï","I" },  //umlaut mark
    {"Ð","Eth"}, //Icelandic
    {"Ñ","N" },  //tilde
    {"Ò","O" },  //grave accent
    {"Ó","O" },  //acute accent
    {"Ô","O" },  //circumflex accent
    {"Õ","O" },  //tilde
    {"Ö","O" },  //umlaut mark
    {"Ø","O" },  //slash
    {"Ù","U" },  //grave accent
    {"Ú","U" },  //acute accent
    {"Û","U" },  //circumflex accent
    {"Ü","U" },  //umlaut mark
    {"Ý","Y" },  //acute accent
    {"Þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
    {"ß","ss"},  //German

    {"à","a" },  //grave accent
    {"á","a" },  //acute accent
    {"â","a" },  //circumflex accent
    {"ã","a" },  //tilde
    {"ä","ae"},  //umlaut mark
    {"å","a" },  //ring
    {"æ","ae"},  //diphthong
    {"ç","c" },  //cedilla
    {"è","e" },  //grave accent
    {"é","e" },  //acute accent
    {"ê","e" },  //circumflex accent
    {"ë","e" },  //umlaut mark
    {"ì","i" },  //grave accent
    {"í","i" },  //acute accent
    {"î","i" },  //circumflex accent
    {"ï","i" },  //umlaut mark
    {"ð","eth"}, //Icelandic
    {"ñ","n" },  //tilde
    {"ò","o" },  //grave accent
    {"ó","o" },  //acute accent
    {"ô","o" },  //circumflex accent
    {"õ","o" },  //tilde
    {"ö","oe"},  //umlaut mark
    {"ø","o" },  //slash
    {"ù","u" },  //grave accent
    {"ú","u" },  //acute accent
    {"û","u" },  //circumflex accent
    {"ü","ue"},  //umlaut mark
    {"ý","y" },  //acute accent
    {"þ","eth"}, //Icelandic - http://en.wikipedia.org/wiki/Thorn_(letter)
    {"ÿ","y" },  //umlaut mark
    };

或者你可以在这里获得整个代码:

http://remy.supertext.ch/2012/08/clean-filenames/

如果您发现遗失的字符,请告诉我。

答案 2 :(得分:2)

某些浏览器不支持带有特殊符号的文件名(例如:space;#@!$)或非Unicode字符,或者导致客户端计算机中的文件名不正确。 这是一篇名为chanext的中文文章,他给出了解决这个问题的完美方法: 本文给出了一个示例代码(用c#编写),以展示如何在所有四种流行的浏览器(IE; Opera; Firefox和Chrome)中获得完美的解决方案 文件名“Microsoft.Asp.Net.doc”和“F ile ;;!@%#^& y.doc”都可以使用作者在本文中提供的方式正确输出。

http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx

答案 3 :(得分:0)

UrlPathEncode仅对类似URL的字符串的“路径”部分进行编码,请尝试使用 Server.UrlEncodeHttpUtility.UrlEncode