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

來源:互聯網
上載者:User

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

      最近被Cookie的問題纏繞了好幾天,由於項目的需要,用戶端和伺服器端都得操作Cookie,而且伺服器端的Cookie都是帶有子鍵的,以前做用戶端讀取,設定和刪除Cookie的代碼(偷懶),都是google下來的,並且都是無子鍵形式:name=value格式的,於是乎,在沒有徹底弄清楚Cookie之前,對copy下來的代碼進行了少許的修改,便用到了自己的網站上面去,最後很是鬱悶,一連好幾天都是出現Cookie讀寫的問題,實在沒辦法了,今天把Cookie的知識重新瞭解鞏固了一番,才弄清楚其中的緣由。
      首先看一下下面的Cookie簡明參考:(來自:http://www.builder.com.cn/2007/1024/576287.shtml)
  一 寫入Cookie
  1. Name 和 Value 屬性由程式設定,預設值都是Null 參考。
  2. Domain屬性的預設值為當前URL的網域名稱部分,不管發出這個cookie的頁面在哪個目錄下的。
  例如,http://www.cnblogs.com/bmwchampion/archive/2009/08/31/aspnet_js_cookie.html?opt=1頁面中發出一個cookie,Domain屬性預設就是http://www.cnblogs.com/bmwchampion/archive/2009/08/31/aspnet_js_cookie.html?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 第一次Client Access Server,會得到一個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="/"即可

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.