ASP.Net和JS對Cookie的互操作問題

    首先看一下下面的Cookie簡明參考:(來自:http://www.builder.com.cn/2007/1024/576287.shtml)
  一 寫入Cookie
  1. Name 和 Value 屬性由程序設定,默認值都是空引用。
  2. Domain屬性的默認值爲當前URL的域名部分,不管發出這個cookie的頁面在哪個目錄下的。
  例如,http://www.cnblogs.com/bmwchampion/admin/EditPosts.aspx?opt=1頁面中發出一個cookie,Domain屬性缺省就是http://www.cnblogs.com/bmwchampion/admin/EditPosts.aspx?opt=1,可以由程序設置此屬性爲需要的值。
  3. Path屬性的默認值是根目錄,即 ”/” ,不管發出這個cookie的頁面在哪個目錄下的。可以由程序設置爲一定的路徑來進一步限制此cookie的作用範圍。
  4. Expires 屬性,這個屬性設置此Cookie 的過期日期和時間。如果沒有設置 Cookie 的有效期(默認設置),也可以創建 Cookie,但它不會保存到用戶的硬盤上,而是會成爲用戶會話信息的一部分,關閉瀏覽器或會話超時這個Cookie即會消失,這種Cookie稱作非永久性的 Cookie。存放SessionID的Cookie就是這樣的一種Cookie,它不存放在硬盤上,只存在內存之中。
  5. 將要發出的Cookie附加到Response的Cookies屬性中就可以將此Cookie發送到客戶端:Reponse.Cookies.Add(Cookie)
  6. Domain屬性+Path屬性 相同的所有Cookie 在客戶端都存在一個文件中,Cookie之間以”*”分割。每個Cookie的第一行是 Cookie 的名稱,第二行是值,第三行是Domain屬性+Path屬性組成的一個字符串,指示此Cookie的作用域,其餘各行則包含 Cookie 的日常處理信息,例如過期日期和時間。Cookie 中還有一個簡單的校驗和,如果更改 Cookie 名稱或值的長度,瀏覽器就會檢測到修改並刪除該 Cookie。
  二 讀取Cookie
  1. Request.Cookies 屬性中包含了客戶端發送到服務器的所有Cookie的集合,只有在請求URL的作用範圍內的Cookie纔會被瀏覽器連同Http請求一起發送到服務器。
  2. Name 和 Value 屬性和子鍵的值很容易讀到。
  3. Domain 和 Path 屬性 是讀不到的,讀Domain屬性永遠是””,讀Path屬性永遠是 ”/” 。本來這些屬性的用途很有限。如果您的頁面與 Cookie 不在相同的域,您根本就不會在頁面的位置接收到該 Cookie。
  4. 也無法讀取Cookie 的過期日期和時間。事實上,當瀏覽器向服務器發送 Cookie 信息時,瀏覽器並未將過期信息包括在內。您可以讀取 Expires 屬性,但總是返回爲零的日期/時間值。Expires 屬性的主要作用是幫助瀏覽器執行有關 Cookie 保存的日常管理。從服務器的角度來看,Cookie 要麼存在要麼不存在,所以對服務器而言,有效期並不是有用的信息。
所以,瀏覽器在發送 Cookie 時並不提供此信息。如果您需要 Cookie 的過期日期,就必須重新設置。
  三 修改和刪除 Cookie
  1. 其實你不能直接修改一個Cookie,是創建一個同名的 Cookie,並把該 Cookie 發送到瀏覽器,覆蓋客戶機上舊的 Cookie。
  2. 同樣您無法直接將其刪除一個Cookie,可以通過修改一個Cookie達到讓瀏覽器幫你刪除Cookie的目的,修改Cookie的有效期爲過去的某個時間,當瀏覽器檢查 Cookie 的有效期時,就會刪除這個已過期的 Cookie。
  四 Cookie同Session的關係
  1. asp.net中Session可以採用cookie 和cookieless兩種方法,cookieless方式是將SessionID放在URL中在客戶端和服務端中來回傳遞,不需要用到cookie,在這裏不討論這個方式。
  2. 在asp.net中客戶第一次請求一個URL,服務器給這個客戶生成一個SessionID,並以非永久性的 Cookie發送到客戶端。
  3. 非永久性的 Cookie只有在瀏覽器關閉後這些Cookie才隨之消失,Session的超時判斷是這樣的過程:
  3.1 第一次客戶端訪問服務器,會得到一個SessionID,以非永久性的 Cookie發送到客戶端。
  3.2 在這個瀏覽器關閉之前訪問這個URL,瀏覽器都會把這個SessionID發送到服務端,服務端根據SessionID來維持對應此客戶的服務端的各種狀態(就是Session中保存的各種值),在web應用程序中可以對這些Session進行操作。
  3.3 服務端維護此SessionID的過期時間,IIS中可以設置Session的超時時間。每次請求都將導致服務端將此SessioID的過期時間延長一個設置的超時時間。
  3.4 當服務端發現某個SessionID已經過時,即某個客戶已經在設置的超時時間內沒有再次訪問此站點,即將此SessionID,連同跟此SessionID相關的所有Session變量刪除。
  3.5 客戶端的瀏覽器未關閉前,並不知道服務端已經將這個SessionID刪除,客戶端依舊發送此SessionID的cookie到服務端,只是此時的服務端已經不認識此SessionID了,會將此用戶當做新用戶,再次分配一個新的SessionID。
       然後我把客戶端增刪改Cookie的代碼以及服務器端增刪改Cookie的代碼都貼出來:

js增刪改Cookie:

        //JS操作cookies方法!
        //寫cookies
        function setCookie(value, name, key) {
            var Days = 2;
            var exp = new Date();
            exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
            if (key == null || key == "") {
                document.cookie = name + "=" + encodeURI(value) + ";expires=" + exp.toGMTString()+";path=/";
            }
            else {
                var nameValue = getCookie(name);
                if (nameValue == "") {
                    document.cookie = name + "=" + key + "=" + encodeURI(value) + ";expires=" + exp.toGMTString() + ";path=/";
                }
                else {
                    var keyValue = getCookie(name, key);
                    if (keyValue != "") {
                        nameValue = nameValue.replace(key + "=" + keyValue, key + "=" +encodeURI ( value));
                        document.cookie = name + "=" + nameValue + ";expires=" + exp.toGMTString() + ";path=/";
                    }
                    else {                                          
                        document.cookie = name + "=" + nameValue + "&" + key + "=" + encodeURI(value) + ";expires=" + exp.toGMTString() + ";path=/";
                    }
                }
            }
        }
        //讀取cookies
        function getCookie(name,key) {
            var nameValue = "";
            var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
            if (arr = document.cookie.match(reg)) {
                nameValue = decodeURI(arr[2]);
            }
            if (key != null && key != "") {
                reg = new RegExp("(^| |&)" + key + "=([^(;|&|=)]*)(&|$)");
                if (arr = nameValue.match(reg)) {
                    alert( decodeURI (arr[2])); return decodeURI(arr[2]);
                }
                else return "";
            }
            else {
                return nameValue;
            }
        }
        //刪除cookies
        function delCookie(name) {
            var exp = new Date();
            exp.setTime(exp.getTime() - 1);
            var cval = getCookie(name);
            if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
        }

ASP.NET服務器端操作Cookie的代碼(示例):
protected void showCookieButton_Click(object sender, EventArgs e)
    {
        string name = this.NameServerTextBox.Text;
        string key = this.KeyServerTextBox.Text;
        if (Request.Cookies[name] != null && Request.Cookies [name][key]!=null )
        {
            this.showCookieServerTextBox.Text =Server.UrlDecode ( Request.Cookies[name][key]);
        }
    }
    protected void setCookieServerButton_Click(object sender, EventArgs e)
    {
        string name = this.NameServerTextBox.Text;
        string key = this.KeyServerTextBox.Text;
        HttpCookie httpCookie ;
        if (Request.Cookies[name] == null)
        {
            httpCookie = new HttpCookie(name);
            httpCookie.Path = "/";
            httpCookie.Expires = DateTime.Now.AddDays(2);
            if(key.Trim ()!=string .Empty )
                httpCookie[key] =Server.UrlEncode ( this.setCookieServerTextBox.Text);
            else
                httpCookie.Value = Server.UrlEncode(this.setCookieServerTextBox.Text);
            Response.Cookies.Add(httpCookie);
        }
        else
        {

 

 

            try
            {
                httpCookie = Request.Cookies[name];
                if(key.Trim()== string.Empty )
                    httpCookie.Value = Server.UrlEncode(this.setCookieServerTextBox.Text);
                else
                    httpCookie[key] = Server.UrlEncode(this.setCookieServerTextBox.Text);
                httpCookie.Expires = DateTime.Now.AddDays(2);
                httpCookie.Path = "/";
                Response.Cookies.Add(httpCookie);

                //註釋中的這種方法只給 name-key對應的cookie值賦值了,如果在name下面,還有其他的子鍵的話,其他的子鍵的值都丟失了
                //if(key.Trim ()== "")
                //    Response.Cookies[name].Value = Server.UrlEncode(this.setCookieServerTextBox.Text);
                //else
                //    Response.Cookies[name][key] = Server.UrlEncode(this.setCookieServerTextBox.Text);
                //Response.Cookies[name].Expires = DateTime.Now.AddDays(2);
                //Response.Cookies[name].Path = "/";  
            }
            catch (Exception ep)
            {
            }
                         
        }
    }
//代碼結束

 

 

       這裏需要注意的是,Cookie的Path屬性,必須在客戶端和服務器端同時設置 Path="/"屬性,才能js和ASP.NET對Cookie的操作才能相互作用!另外一個是編碼的問題,這裏JS中的編碼爲encodeURI對應ASP.NET的Server.URLEncode。
       主要原因是雙方對Path的默認值定義不一樣造成

       The problem was actually due to a conflict in domain and path names in my cookie. The .NET control, apparently by default, built my cookie using the domain name and the root path. JavaScript, apparently by default, built my cookie using the domain name and FULL path.
       我們只需要設置同樣的Path="/"即可


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章