客戶端Cookie中文編程 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- 客戶端Cookie中文編程 (http://www.webasp.net/article/13/12509.htm) |
| -- 作者:未知 -- 發佈日期: 2004-08-23 |
| 在Cookie的使用中,我們發現這樣一個問題:如果寫入Cookie的內容是中文(如用戶稱呼),用服務器端程序(如ASP
或PHP)讀出完全正確,但是用一般的JavaScript或VBScript的讀Cookie函數取出的卻是一堆亂碼。這是一個棘手的問題, 因為在有些情況下,Cookie的內容需要在客戶機端用腳本語言讀取。如果你寫入了中文,得到了一堆亂碼,是不是感覺很 彆扭呢?解決這個問題,還要從Cookie的存取方式說起。 我們知道,寫入Cookie內容前需要進行escape(十六進制編碼),編碼時又是以字節為單位的,這就是問題的關鍵所 在:任何一個漢字都會被拆成兩個字節分別編碼;而在讀Cookie時,unescape又以字節單位解碼,因此最後每個漢字都變 成了兩個字節的亂碼。怎麼辦呢?ASP或PHP方式能夠正確讀出,應該是在unescape解碼後,又按照unicode編碼把其中的漢 字拼了出來。如果這樣的話,能不能找到一種變通的方法解決這個問題呢?仔細研究後發現,只要在十六進制codec(編解 碼)過程中能夠保存漢字信息就行了,因而我們需要再外包一層codec過程,方案如下: 1.在escape編碼前,把Cookie字符串中的每個字符轉換為unicode碼的字符串形式(用一特殊字符作為字串的分隔 符)。 2.在unescape解碼後,先把所有unicode字串提取出來,再用對應的函數轉換為原字符。 <SCRIPT LANGUAGE=javascript> <!-- //編碼程序: function CodeCookie(str) { var strRtn=""; for (var i=str.length-1;i>=0;i--) { strRtn+=str.charCodeAt(i); if (i) strRtn+="a"; //用a作分隔符 } return strRtn; } //解碼程序: function DecodeCookie(str) { var strArr; var strRtn=""; strArr=str.split("a"); for (var i=strArr.length-1;i>=0;i--) strRtn+=String.fromCharCode(eval(strArr[i])); return strRtn; } //--> </script> VBScript版程序如下: <SCRIPT LANGUAGE=vbscript> <!-- "編碼程序: function CodeCookie(str) Dim i Dim strRtn for i=len(str) to 1 step -1 strRtn=strRtn & ascw(mid(str,i,1)) if (i<>1) then strRtn = strRtn & "a" "用a作分隔符 next CodeCookie=strRtn end function "解碼程序: function DecodeCookie(str) Dim i Dim strArr,strRtn strArr=Split(str,"a"); for i=UBound(strArr)-LBound(strArr) to 1 step -1 strRtn=strRtn & chrw(Val(strArr(i))) next DecodeCookie=strRtn end function --> </script> 例如你要寫入的Cookie內容是"一頂abc",經過CodeCookie變為"99a98a97a-31029a26432a"(基於安全考慮,將 字符串反轉),再經過escape編碼後變為"99a98a97a%2D31029a26432a"(escape編碼將除字母和數字以外的字符轉換為十 六進制%XX的形式),注意分隔符不能選%,D和數字。當然,如果有類似密碼的重要信息,還需要在加密上再強化一下。因 為寫入Cookie的一般都是短信息,編碼後增加的一些字節可忽略不計。下面的JavaScript讀寫Cookie函數中就加入了以上 的中文支持。 function SetCookie(name,value,expires) { var exp=new Date(); exp.setTime(exp.getTime()+expires*60*1000); document.cookie=name+"="+escape(CodeCookie(value))+" ; expires="+exp.toGMTString()+" ; path=/"; } function GetCookie (name) { var strArg=name+"="; var nArgLen=strArg.length; var nCookieLen=document.cookie.length; var nEnd; var i=0; var j; while (i<nCookieLen) { j=i+nArgLen; if (document.cookie.substring(i,j)==strArg) { nEnd=document.cookie.indexOf (";",j); if (nEnd==-1) nEnd=document.cookie.length; return DecodeCookie(unescape(document.cookie.substring(j,nEnd))); } i=document.cookie.indexOf(" ",i)+1; if (i==0) break; } return null; } 如果用CGI程序寫入中文Cookie,客戶端讀取。如在ASP裡,可以先使用前述的編碼函數後,再用response寫入,例 如:response.cookies("Name")=CodeCookie("張三")至此,中文Cookie的問題基本解決。若有相關問題,請到 www.coolbel.com/saibai交流。 |
| webasp.net |