Request 接收參數亂碼原理解析三:實例分析

      經過前面兩篇《Request 接收參數亂碼原理解析一:服務器端解碼原理》和《Request 接收參數亂碼原理解析二:瀏覽器端編碼原理》,瞭解了服務器和瀏覽器編碼解碼的原理,接下來結合項目中遇到的具體問題,分析亂碼問題的解決方法。javascript

      1.用戶身份驗證Cookie亂碼問題html

      用戶登陸後,一般用Cookie記錄身份,如把用戶名記錄到Cookie中,其它頁面讀取Cookie,對Cookie值驗證,符合必定規則的話則認爲是合法用戶。java

        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結點指定的。web

      這段代碼絕大部分運行是沒問題的,但遇到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"))」。ajax

    <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解)。ide

            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)。函數

相關文章
相關標籤/搜索