JavaScript Cookie 读写中 Domain 冲突与解决方案
本文探讨了在 JavaScript 中读写 Cookie 时,相同 Key 但不同 Domain(如 localhost.dev.xxx.com 与 xxx.com)共存导致的读取冲突问题。由于 document.cookie 无法返回 Domain 信息,导致获取值可能错误。文章提出将 Cookie 统一写入根域名的解决方案,并提供了包含版本控制、过期时间处理及清理旧版 Cookie 的完整 JS 实现代码。
Cookie Domain 冲突与读取限制
在使用 JavaScript 进行 Cookie 读写时,常忽略一个关键细节:即使 Key 值相同,只要 Domain 不同(例如 localhost.dev.xxx.com、dev.xxx.com 以及 xxx.com),这些 Cookie 可以同时存在于浏览器中。通过 document.cookie 可以读取到所有这些同名 Cookie,但该属性并不返回 Domain 信息。目前尚未找到直接读取 Cookie Domain 信息的方法,如有相关技巧欢迎补充。
1 var cookieDomain = document.domain; 2 3 var tmp = location.hostname.split(.); 4 5 if(tmp.length > 2)6 7 cookieDomain = tmp.slice(1).join(.); 写 cookie 的时候,我把 domain 设为这个 cookieDomain , 这样一来, 不同的坏境的 cookie 就会写到不同的 domain 下面, 看似互不影响. 但是在取的时候, 可以取出来N个相同的 key 的 cookie 值来! 而我只取第一次出现的 cookie, 这样就造成了取出的值很有可能是错的. 就这个问题, 客户单位像狗皮膏药一样贴住我了!跟他们解释了N次,说你们对外只提供一个网址, 浏览者的电脑不会出现取值错误的情况(因为只有一个 domain ). 可是牙的每次BUG汇总里,总会把这个问题列出来! 所有解释等于对牛弹琴. 木折, 那我就把所有用 js 写的 cookie 写到根域名下吧, 省得这帮家伙叫来叫去,大问题不关注,小问题看贼细贼,本末倒置!
根域名写入与清理实现方案
具体实现代码如下:
(function(){
// 清除旧版本的 cookie
if(CTSZ.Cookie.get("cookieVersion") != Params.cookieVersion){
var tmps = Params.orgDomain.split(.);
var domain;
var len = tmps.length;
for(var i=0;i<= len - 3; i++){
tmps.shift();
domain = tmps.join(.);
CTSZ.Cookie.empty("/", domain);
}
CTSZ.Cookie.set("cookieVersion", Params.cookieVersion, Params.cookieExpires, "/", Params.cookieDomain);
}
})();
$.Cookie = {};
(function ($) {
$.getExpires = function (y, m, d, h, i, s, ms) {
var date = new Date();
y = isNaN(y) ? date.getFullYear() : y;
m = isNaN(m) ? date.getMonth() : m - 1;
d = isNaN(d) ? date.getDate() : d;
h = isNaN(h) ? date.getHours() : h;
i = isNaN(i) ? date.getMinutes() : i;
s = isNaN(s) ? date.getSeconds() : s;
ms = isNaN(ms) ? date.getMilliseconds() : ms;
return new Date(y, m, d, h, i, s, ms).toUTCString();
}
$.getExpiresByUTCString = function (UTCString) {
var s = new Date(UTCString).toUTCString();
if (s == NaN || s == Invalid Date)
return null; // IE,Opera NaN , FF,Safari Invalid Date;
else
return s;
}
$.set = function (k, v, expires, path, domain, secure) {
var cookie = k + = + encodeURIComponent(v);
if (expires) cookie += ";expires=" + expires;
if (path) cookie += ";path=" + path;
if (domain) cookie += ";domain=" + domain;
if (secure) cookie += ";secure";
document.cookie = cookie;
}
/*
以前是把所有 cookie 都取出放到一个对象里,在 get 的时候,直接从那个对象里取来,现在想想,那样并不正确。因为假如某个 cookie 的过期时间过了,那个对象并没有更新。
*/
$.get = function (k) {
var cks = document.cookie.split(;);
var t;
for (var i = 0; i < cks.length; i++) {
t = cks[i].split(=);
if (k == t[0].trim()) return t.length >= 2 ? decodeURIComponent(t[1]) : "";
}
return null;
}
$.remove = function (k, path, domain) {
$.set(k, , $.getExpires(new Date().getFullYear() - 1), path, domain);
}
$.empty = function (path, domain) {
var cks = document.cookie.split(;);
var t;
for (var i = 0; i < cks.length; i++) {
$.remove(cks[i].split(=)[0].trim(), path, domain);
}
}
})($.Cookie);JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
