js實(shí)現(xiàn)一二級域名共享cookie
前言
最近接手的項(xiàng)目中 ,有人反饋了一個(gè)問題,說是在訪問網(wǎng)站并登錄后,登錄成功有登錄信息,但是刷新頁面后重定向到了登錄頁面,讓從新登錄。
打開 goole 調(diào)試頁面,查看 cookie 時(shí)發(fā)現(xiàn)存儲的相關(guān) token 信息不見了。
原本以為 cookie 有效期有問題,但經(jīng)過排查 cookie 失效為 7 天,也沒有清除 cookie 的邏輯。
經(jīng)排查發(fā)現(xiàn):我們在輸入訪問 hew.cn 的時(shí)候,刷新頁面網(wǎng)址變成了www.hew.cn 導(dǎo)致原本存儲在 hew.cn 域名下的 cookie 信息沒有同步到www.hew.cn下。
也就是所謂的:二級域名和頂級域名不共享的原因而引起的 cookie
原理
我們往往在開發(fā)過程中在存儲 cookies 時(shí),不會特意去加上 domain 屬性,這樣會默認(rèn)存放在當(dāng)前域名下。因此我們在訪問www.hew.cn頁面只會攜帶上,存放在當(dāng)前域名下的token信息,而我們通過瀏覽器輸入www.hew.cn其實(shí)訪問的頂級域名是hew.cn,二者是父子級其實(shí)是關(guān)系。
我們這樣存儲 cookie 會二級子域名下的 cookie 和頂級域名不共享的。同理 a.hew.com 下設(shè)置 cookie, 在 b.hew.com 下也是無法正常使用的
要避免這樣的原因,我們就需要設(shè)置 cookie 的 domain
cookie 相關(guān)配置
| 屬性 | 介紹 |
|---|---|
| name | Cookie 的名稱,Cookie 一旦創(chuàng)建,名稱便不可更改 |
| value | Cookie 的值,如果值為 Unicode 字符,需要為字符編碼。如果為二進(jìn)制數(shù)據(jù),則需要使用 BASE64 編碼 |
| maxAge | Cookie 失效的時(shí)間,單位秒。如果為整數(shù),則該 Cookie 在 maxAge 秒后失效。如果為負(fù)數(shù),該 Cookie 為臨時(shí) Cookie,關(guān)閉瀏覽器即失效,瀏覽器也不會以任何形式保存該 Cookie。如果為 0,表示刪除該 Cookie。默認(rèn)為-1。 |
| secure | 該 Cookie 是否僅被使用安全協(xié)議傳輸。安全協(xié)議。安全協(xié)議有 HTTPS,SSL 等,在網(wǎng)絡(luò)上傳輸數(shù)據(jù)之前先將數(shù)據(jù)加密。默認(rèn)為 false。 |
| path | Cookie 的使用路徑。如果設(shè)置為“/sessionWeb/”,則只有 contextPath 為“/sessionWeb”的程序可以訪問該 Cookie。如果設(shè)置為“/”,則本域名下 contextPath 都可以訪問該 Cookie。注意最后一個(gè)字符必須為“/”。 |
| domain | 可以訪問該 Cookie 的域名。如果設(shè)置為“.google.com”,則所有以“google.com”結(jié)尾的域名都可以訪問該 Cookie。注意第一個(gè)字符必須為“.”。 |
| comment | 該 Cookie 的用處說明,瀏覽器顯示 Cookie 信息的時(shí)候顯示該說明。 |
| version | Cookie 使用的版本號。0 表示遵循 Netscape 的 Cookie 規(guī)范,1 表示遵循 W3C 的 RFC 2109 規(guī)范 |
通過上方 cookie 相關(guān)配置我們可以看到 domain 屬性 可以有效進(jìn)行一二級域名共享 cookie
代碼實(shí)現(xiàn)
<script>
document.cookie="name=value;domain=hew.cn";
</script>
簡單封裝一個(gè)獲取、設(shè)置、刪除 cookie 的工具類 CookieTool
/**
* @params name cookie鍵
* @params value cookie值
* @params days cookie過期時(shí)間
*/
export function setCookie(name, value, days) {
var domain, domainParts, date, expires, host;
// 設(shè)置過期時(shí)間 格林威治時(shí)間 (GMT)
if (days) {
date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
} else {
expires = "";
}
// 獲取域名
host = location.host;
if (host.split('.').length === 1) {
document.cookie = name + "=" + value + expires + "; path=/; domain=." + host;
} else {
domainParts = host.split('.');
domainParts.shift();
domain = '.' + domainParts.join('.');
document.cookie = name + "=" + value + expires + "; path=/; domain=" + domain;
if (getCookie(name) == null || getCookie(name) != value) {
domain = '.' + host;
document.cookie = name + "=" + value + expires + "; path=/; domain=" + domain;
}
}
}
export function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)")
if (arr = document.cookie.match(reg))
return unescape(arr[2])
else
return null
}
export 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();
}
</script>

浙公網(wǎng)安備 33010602011771號