伺服器端 (C#) 操作 Cookie
寫入單一值
HttpCookie cookie = new HttpCookie("UserPref", "DarkMode");
cookie.Expires = DateTime.Now.AddDays(30);
cookie.HttpOnly = true; // 防 XSS
cookie.Secure = true; // 僅 HTTPS
Response.Cookies.Add(cookie);
寫入多子鍵
HttpCookie cookie = new HttpCookie("UserSettings");
cookie.Values["Theme"] = "Dark";
cookie.Values["Lang"] = "zh-TW";
cookie.Values["FontSize"] = "14";
cookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(cookie);
讀取
// 單值
string theme = Request.Cookies["UserPref"]?.Value;
// 多子鍵
if (Request.Cookies["UserSettings"] is HttpCookie c) {
string lang = c.Values["Lang"];
foreach (string key in c.Values.AllKeys) {
Response.Write($"{key} = {c.Values[key]}<br/>");
}
}
刪除 / 更新
// 刪除整個 Cookie
Response.Cookies.Remove("UserPref");
// 或設定過期
HttpCookie c = new HttpCookie("UserPref") { Expires = DateTime.Now.AddDays(-1) };
Response.Cookies.Add(c);
// 刪除單一子鍵
if (Request.Cookies["UserSettings"] is HttpCookie c2) {
c2.Values.Remove("FontSize");
Response.Cookies.Set(c2); // 必須用 Set 寫回
}
客戶端 (JavaScript) 操作 Cookie
通用工具函式
// 設定 Cookie
function setCookie(name, value, days) {
let expires = "";
if (days) {
const d = new Date();
d.setTime(d.getTime() + days * 864e5);
expires = "; expires=" + d.toUTCString();
}
document.cookie = `${name}=${encodeURIComponent(value)}${expires}; path=/; SameSite=Lax`;
}
// 讀取 Cookie
function getCookie(name) {
const match = document.cookie.match(new RegExp('(^|;\\s*)' + name + '=([^;]+)'));
return match ? decodeURIComponent(match[2]) : null;
}
// 刪除 Cookie
function deleteCookie(name) {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax`;
}
// 解析多子鍵格式(ASP.NET 預設 key1=val1&key2=val2)
function parseAspNetCookie(raw) {
const obj = {};
raw.split('&').forEach(pair => {
const [k, v] = pair.split('=');
obj[decodeURIComponent(k)] = decodeURIComponent(v);
});
return obj;
}
完整範例:CheckBox 狀態持久化
ASPX 頁面
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) LoadPreferences();
}
protected void btnSave_Click(object sender, EventArgs e) {
HttpCookie cookie = new HttpCookie("MyChecks");
for (int i = 1; i <= 5; i++) {
CheckBox cb = FindControl($"CheckBox{i}") as CheckBox;
if (cb != null) cookie.Values[$"Chk{i}"] = cb.Checked.ToString();
}
cookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(cookie);
LoadPreferences(); // 重新顯示
}
void LoadPreferences() {
if (Request.Cookies["MyChecks"] is HttpCookie c) {
for (int i = 1; i <= 5; i++) {
CheckBox cb = FindControl($"CheckBox{i}") as CheckBox;
if (cb != null && c.Values[$"Chk{i}"] != null)
cb.Checked = bool.Parse(c.Values[$"Chk{i}"]);
}
}
}
</script>
<html><body><form runat="server">
<asp:CheckBox ID="CheckBox1" runat="server" Text="選項 1" /><br/>
<asp:CheckBox ID="CheckBox2" runat="server" Text="選項 2" /><br/>
<asp:CheckBox ID="CheckBox3" runat="server" Text="選項 3" /><br/>
<asp:CheckBox ID="CheckBox4" runat="server" Text="選項 4" /><br/>
<asp:CheckBox ID="CheckBox5" runat="server" Text="選項 5" /><br/>
<asp:Button ID="btnSave" Text="儲存偏好" OnClick="btnSave_Click" />
<hr/>
<button onclick="clearClientCookie()">JS 清除 Cookie</button>
<script>
function clearClientCookie() {
document.cookie = "MyChecks=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
alert("已清除,重新整理頁面查看效果");
}
</script>
</form></body></html>
進階主題
跨子網域共享
cookie.Domain = ".example.com"; // 前面加點號,所有子網域可讀
// 需在 web.config 同步設定
<system.web>
<httpCookies domain=".example.com" />
</system.web>
SameSite 屬性 (ASP.NET 4.7.2+)
cookie.SameSite = SameSiteMode.Lax; // 預設 Lax,可設 None(需 Secure=true)
// web.config 全域
<system.web>
<httpCookies sameSite="Lax" />
</system.web>
安全性最佳實務
- 敏感資料勿存 Cookie,改用 Server-side Session / 加密 Token。
- 啟用
HttpOnly 防止 JS 竊取,Secure 強制 HTTPS 傳輸。
- 設定
SameSite=Lax/Strict 防禦 CSRF。
- 定期輪換加密金鑰(
machineKey),避免 Cookie 被偽造。
常見問題
| 現象 | 原因 | 解決 |
| Request.Cookies 為 null | 瀏覽器未送出(路徑、網域、SameSite 不符) | 檢查 Path=/、Domain、SameSite 設定一致 |
| 子鍵讀取失敗 | ASP.NET 多值編碼為 & 分隔,JS 需自行解析 | 使用 parseAspNetCookie 或改存 JSON 字串 |
| Cookie 超過 4KB | 單一 Cookie 上限 4096 bytes | 拆分多 Cookie 或改用 LocalStorage/SessionStorage |