我正在使用 HttpHandler 子级中实现的 HttpContext 对象来下载文件,当文件名中包含非 ascii 字符时,它在 IE 中看起来很奇怪,而在 Firefox 中看起来很好。

下面是代码:-

       context.Response.ContentType = ".cs";
context.Response.AppendHeader("Content-Length", data.Length.ToString());
context.Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}",filename));
        context.Response.OutputStream.Write(data, 0, data.Length);

context.Response.Flush();

当我在文件名字段中提供 'Ù' '¤' '¶' 'Õ' 'Ú' 'Ù' '¤' '¶' 'Ñ' 'Ú' 时,它看起来与我在文件中的不同名字它在火狐浏览器中看起来不错。添加 EncodingType 和 charset 没有用。

在 ie 中是 'å¸''ä''ö''ü''ó''ß''ä''ö''�'_'��,在 Firefox 中是 '�' '�' '�¶' '���' '�' '�' '��' '�¶' '���' ��。

知道如何解决这个问题吗?

有帮助吗?

解决方案

我有类似的问题。你必须使用 HttpUtility.UrlEncode 或者 服务器.UrlEncode 对文件名进行编码。我还记得firefox不需要它。此外,当文件名进行 url 编码时,它会破坏文件名。我的代码:

// IE needs url encoding, FF doesn't support it, Google Chrome doesn't care
if (Request.Browser.IsBrowser ("IE"))
{
    fileName = Server.UrlEncode(fileName);
}

Response.Clear ();
Response.AddHeader ("content-disposition", String.Format ("attachment;filename=\"{0}\"", fileName));
Response.AddHeader ("Content-Length", data.Length.ToString (CultureInfo.InvariantCulture));
Response.ContentType = mimeType;
Response.BinaryWrite(data);

编辑

我已经更仔细地阅读了规范。首先 RFC2183 指出:

当前的 [RFC 2045] 语法将参数值(以及内容处理文件名)限制为 US-ASCII。

但后来我发现 [RFC 2045] 的参考资料已经过时,必须参考 RFC 2231, ,其中指出:

重复使用星号(“*”)以提供以下指标:语言和字符集存在并使用编码。单个报价(“'”)用于在参数值开始时界定字符集和语言信息。百分比(“%”)用作编码标志,与RFC 2047一致。

这意味着您可以对非 ascii 符号使用 UrlEncode,只要您包含中所述的编码即可 射频卡. 。这是一个例子:

string.Format("attachment; filename=\"{0}\"; filename*=UTF-8''{0}", Server.UrlEncode(fileName, Encoding.UTF8));

注意 filename 还包括 filename* 为了向后兼容。您还可以选择其他编码并相应地修改参数,但 UTF-8 涵盖了所有内容。

其他提示

HttpUtility.UrlPathEncode可能是一个更好的选择。正如将URLEncode的替换 '+' 标志位。

对我来说,这个解决方案适用于所有主要浏览器:

Response.AppendHeader("Content-Disposition", string.Format("attachment; filename*=UTF-8''{0}", HttpUtility.UrlPathEncode(fileName).Replace(",", "%2C"));
var mime = MimeMapping.GetMimeMapping(fileName);
return File(fileName, mime);

使用 ASP.NET MVC 3。

Replace 是必要的,因为 Chrome 不喜欢在参数值中使用逗号 (,): http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/

您可能想在在的 RFC 6266 和外观= “http://greenbytes.de/tech/tc2231/” 相对= “nofollow”> http://greenbytes.de/tech/tc2231/ 。

有关我此解决了这个问题:

var result = new HttpResponseMessage(HttpStatusCode.OK)
{
   Content = new ByteArrayContent(data)
};

result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileNameStar = "foo-ä-€.html"
};

当我看广告在Fiddler中repsonse我可以看到的文件名已经automaticcaly一直使用UTF-8编码:

使用文件名的Fiddler响应具有编码内容处置例如UTF-8

如果我们看一下内容处置头的值,我们可以看到这将是一样@Johannes格耶他的答案。唯一的区别是,我们并没有做编码ourselfs,该ContentDispositionHeaderValue类需要的照顾。

我用于在内容处理标头的测试用例: http://greenbytes.de/tech/ tc2231 / 由儒略雷什克提及。 关于ContentDispositionHeaderValue类信息可以在MSDN上找到。

有关Asp.Net核心(第2版,因为这后)UrlPathEncode已过时,这里是如何实现所期望的结果:

System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
   FileName = Uri.EscapeUriString(fileName),
   Inline = true  // false = prompt the user for downloading;  true = browser to try to show the file inline
};

Response.Headers.Add("Content-Disposition", cd.ToString());

我真的使用Uri.EscapeUriString用于转换所有字符的十六进制表示,并且string.Normalize Unicode的归一化形式C. (在测试的ASP.NET框架MVC5 4.5)

    var contentDispositionHeader = new System.Net.Mime.ContentDisposition
    {
        Inline = false,
        FileName = Uri.EscapeUriString(Path.GetFileName(pathFile)).Normalize()
    };
    Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString());
    string mimeType = MimeMapping.GetMimeMapping(Server.MapPath(pathFile));
    return File(file, mimeType);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top