zoukankan      html  css  js  c++  java
  • ASP .net文件下载乱码

    在 asp.net 项目中,我们可以很方便地使用 Response.WriteFile() 方法向客户端输出一个文件。实际使用 asp.net  HttpContextBase

    页面编码为UTF-8,各种浏览器的默认编码也是UTF-8,可是为什么会出现乱码????

    问题现象

    当原文件的文件名中含有空格、中文、&等非 ASCII 字符,就出现乱码。特殊字符不能正常的输出。

    当原文件名包含空格时,默认将被改成下划线,即“_”。

    如果我们在输出文件时对文件名使用 UrlEncode() 对其进行编码,空格将变成加号,即“+”。

    当原文件名包含中文或其他非英文字符时,由于编码的错误,默认情况很糟糕,竟然完全是无法辨识的乱码。

    如果我们在输出文件时对文件名进行 UrlEncode() 对其进行编码,这些中文将能正确地被显示; 但是,在Opera 或 Firefox或者chrome 中,如果经过了 UrlEncode(),它们将无法正确地解析,而不经过 UrlEncode() 却能能正确地显示了。

    解决办法

    Internet Explorer 能在客户端正确显示已经UrlEncode() 的字符(其中 空格 需先转换 Replace("+", "%20"))

    而 Opera 等其他浏览器可以解析未经 UrlEncode() 的直接输出的字符(这意味着,对于使用Opera或其他客户端的客户,我们不应该对它进行 UrlEncode()编码) 。

    解决办法很简单:只需要判断是否为IE浏览器即可,如果为IE就使用System.Web.HttpUtility.UrlEncode(fileName).Replace("+", "%20");否则不经过UrlEncode()

    以下为判断是否为IE浏览器的办法:

    本人使用:context.Request.Browser.Browser == "IE" || context.Request.Browser.Browser == "InternetExplorer"

    以前的老方法:Request.UserAgent.Contains("MSIE") || Request.UserAgent.Contains("msie"));but, 在IE11中Request.UserAgent是 Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko,因此老方法对IE11不起作用。

    以下部分是别人提供的解决方案,仅供参考。

    在输出文件地地方使用的代码:

    if (Request.UserAgent.Contains("MSIE") || Request.UserAgent.Contains("msie")) 
    {         
          // 如果客户端使用 Microsoft Internet Explorer,则需要编码
        fileName = ToHexString(fileName); 
    }

     

     应该置于上述代码同一文件或可访问的其他类的几个函数:

    复制代码
           /// <summary>
            /// 为字符串中的非英文字符编码
            /// </summary>
            /// <param name="s"></param>
            /// <returns></returns>
            public static string ToHexString(string s)
            {
                char[] chars = s.ToCharArray();
                StringBuilder builder = new StringBuilder();
                for (int index = 0; index < chars.Length; index++)
                {
                    bool needToEncode = NeedToEncode(chars[index]);
                    if (needToEncode)
                    {
                        string encodedString = ToHexString(chars[index]);
                        builder.Append(encodedString);
                    }
                    else
                    {
                        builder.Append(chars[index]);
                    }
                }
    
                return builder.ToString();
            }
    
            /// <summary>
            ///指定 一个字符是否应该被编码
            /// </summary>
            /// <param name="chr"></param>
            /// <returns></returns>
            private static bool NeedToEncode(char chr)
            {
                string reservedChars = "$-_.+!*'(),@=&";
    
                if (chr > 127)
                    return true;
                if (char.IsLetterOrDigit(chr) || reservedChars.IndexOf(chr) >= 0)
                    return false;
    
                return true;
            }
    
            /// <summary>
            /// 为非英文字符串编码
            /// </summary>
            /// <param name="chr"></param>
            /// <returns></returns>
            private static string ToHexString(char chr)
            {
                UTF8Encoding utf8 = new UTF8Encoding();
                byte[] encodedBytes = utf8.GetBytes(chr.ToString());
                StringBuilder builder = new StringBuilder();
                for (int index = 0; index < encodedBytes.Length; index++)
                {
                    builder.AppendFormat("%{0}", Convert.ToString(encodedBytes[index], 16));
                }
               return builder.ToString();
            }
    复制代码

    此外,针对一些浏览器做了一些特殊的处理,已经体现在本文示例代码的注释中。此代码已经能非常完好地解决问题了,在 Internet Explorer 、Opera、Firefox 及 Chrome 中得到的体验一致,支持中文,支持空格的正常输出。

  • 相关阅读:
    PHP atanh() 函数
    PHP atan2() 函数
    PHP atan() 函数
    #检查磁盘使用率超过90%,并且后台进程没有rman在跑,就运行 /data/script/del_dg_arch.sh 脚本清理归档
    [学习笔记]自适应辛普森积分
    C# 如何写 DEBUG 输出
    C# 如何写出一个不能被其他程序集继承的抽象类
    C# 如何写出一个不能被其他程序集继承的抽象类
    C# 如何引用 WshShell 类
    C# 如何引用 WshShell 类
  • 原文地址:https://www.cnblogs.com/see-you/p/as.html
Copyright © 2011-2022 走看看