• Request 接收参数乱码原理解析三:实例分析


          通过前面两篇《Request 接收参数乱码原理解析一:服务器端解码原理》和《Request 接收参数乱码原理解析二:浏览器端编码原理》,了解了服务器和浏览器编码解码的原理,接下来结合项目中遇到的具体问题,分析乱码问题的解决方法。

          1.用户身份验证Cookie乱码问题

          用户登录后,通常用Cookie记录身份,如把用户名记录到Cookie中,其它页面读取Cookie,对Cookie值验证,符合一定规则的话则认为是合法用户。

            protected void Page_Load(object sender, EventArgs e)
            {
                //假定登陆用户名为北京(历史原因系统允许有中文名)
                Response.Cookies["username"].Value = Server.UrlEncode("北京");
            }
    登陆成功记录Cookie
            protected void Page_Load(object sender, EventArgs e)
            {
                //读取Cookie,如果用户名存在则认为登陆成功(实际验证比这要复杂很多)
                string userName = Server.UrlDecode(Request.Cookies["username"].Value);
                bool isLogin = userName == "北京";
                Response.Write("用户" + userName + "登陆" + (isLogin ? "成功" : "失败"));
            }
    验证Cookie页面

          因为用户名存在中文问题,写入编码和读取解码都是在服务器端进行的,所以写Cookie时将值用Server.UrlEncode()编码,读取Cookie值时用Server.UrlDecode()解码,通常认为这两个函数是成对出现的,都是由web.config中的globalization结点指定的。

          这段代码绝大部分运行是没问题的,但遇到Post请求的AJax调用页面时,就出错了,得到的username值是乱码。通过前面两篇的分析可知:Ajax请求时,页面请求Header中加了“Content-Type: text/html; charset=utf8”,Server.UrlDecode()解码方式变成了utf-8,乱码自然产生了。问题解决方式是解码时指定编码方式,不要再用依赖于上下文的函数解码了,可以改为“HttpUtility.UrlDecode(Request.Cookies["username"].Value, System.Text.Encoding.GetEncoding("GB2312"))”。

        <form id="form1" runat="server">
            <div>
                <input type="button" name="btnAjaxPost" value="AJax提交" onclick="Ajax()" />
                <div id="divMessage" style="color: red"></div>
            </div>
        </form>
        <script type="text/javascript">
            function Ajax() {
                $.ajax({
                    type: "POST",
                    url: "LoginValidateCookie.aspx",
                    data: { name: "name" },
                    success: function (data) {
                        $("#divMessage").html(data);
                    }
                });
            }
    
        </script>
    Ajax Post请求示例

           2.Url地址栏中的中文参数

           有些页面地址,由于某些原因带了中文参数(如http://localhost:52443/Encode/EncodeTest.aspx?username=北京),而这些地址又可能已经被baidu等搜索引擎收录,因此不能单靠生成新地址规则方式解决,项目必须做到兼容带中文参数的地址。

           如果是类似示例中的逻辑,中文参数为系统用户的用户名,则可以采用先用Request.QueryString方式获取,得到username如果在系统中存在,则认为得到的参数是正确的;如果username在系统中不存在,则认为可能是因为参数中文乱码原因引起的,再用NameValueCollection方式获取一次,解码方式和系统解码是不一样的(系统配置的是GB2312,则指定用utf-8解)。

                string username = Request.QueryString["username"];
                //如果通过Request方式获取参数乱码,则可以通过解析Request.Url.Query的方式获取参数
                NameValueCollection parames = HttpUtility.ParseQueryString(Request.Url.Query, Encoding.UTF8);
                string username2 = parames["username"];

            如果中文参数值是任意值,无法判断是正常值还是乱码,可能就要根据不同浏览器类型,判断用GB2312解码还是utf-8解码了。当然为避免不必要的麻烦,尽量url地址中不要含有中文参数(可通过编码来解决,工行网站就是这么干的,url中的中文用了utf-8编码http://www.icbc.com.cn/ICBC/%e5%ae%a2%e6%88%b7%e6%9c%8d%e5%8a%a1/%e7%83%ad%e7%82%b9%e9%97%ae%e7%ad%94/%e4%b8%aa%e4%ba%ba%e7%94%b5%e5%ad%90%e9%93%b6%e8%a1%8c/default.htm)。

  • 相关阅读:
    NOIP模拟测试2「排列 (搜索)·APIO划艇」
    Linux运维基础
    Linux之权限详解
    Linux之特殊符号与正则表达式
    Linux之命令进阶
    Linux分区的几种方案
    开启MySQL远程访问权限 允许远程连接
    Linux命令
    win10 激活(亲测可用)
    帮你解决无法早起的焦虑-顺便撸羊毛
  • 原文地址:https://www.cnblogs.com/freshman0216/p/4192436.html
Copyright © 2020-2023  润新知