实现Cookie属性的动态Get与Set方法技术求助
你遇到的核心问题是:原来的cookie.c返回的是普通对象,当你对cookie.c.something赋值时,只是修改这个临时对象的属性,根本不会触发类的set c方法——因为你赋值的是对象内部的属性,不是c本身。要实现任意属性的读写拦截,得用ES6的Proxy,它可以拦截对象的所有属性操作,包括未提前定义的属性。
可行实现代码
class Cookie { // 获取原始cookie字符串 static get raw() { return document.cookie; } // 解析cookie为键值对对象 static get object() { const cookieMap = {}; const cookiePairs = Cookie.raw.split(';').map(item => item.trim()); for (const pair of cookiePairs) { const [name, value] = pair.split('='); cookieMap[decodeURIComponent(name)] = decodeURIComponent(value); } return cookieMap; } // 返回代理对象,拦截所有属性读写操作 static get c() { return new Proxy({}, { // 拦截属性读取:返回对应cookie值 get(target, prop) { return Cookie.object[prop]; }, // 拦截属性赋值:更新document.cookie set(target, prop, value) { // 编码避免特殊字符破坏cookie格式 const encodedName = encodeURIComponent(prop); const encodedValue = encodeURIComponent(value); // 基础设置,可扩展路径、过期时间等参数 document.cookie = `${encodedName}=${encodedValue}; path=/`; return true; // 必须返回true表示赋值成功 } }); } }
测试示例
// 设置任意属性的cookie Cookie.c.something = "hello world"; console.log(document.cookie); // 输出: "something=hello%20world; path=/" // 获取已设置的cookie值 console.log(Cookie.c.something); // 输出: "hello world" // 新增其他属性同样生效 Cookie.c.username = "john_doe"; console.log(Cookie.c.username); // 输出: "john_doe"
关键逻辑说明
Proxy的get陷阱:每次读取Cookie.c.xxx时,都会重新解析最新的document.cookie,保证拿到的是实时值。Proxy的set陷阱:每次赋值Cookie.c.xxx = yyy时,自动编码名称和值,直接修改浏览器的document.cookie,支持任意自定义属性名。- 为什么不用原来的
set c?因为类的set c只能拦截对Cookie.c本身的赋值(比如Cookie.c = { ... }),无法拦截其内部属性的赋值操作,这是JavaScript getter/setter的特性决定的。
扩展建议(可选)
如果需要支持cookie的高级参数(过期时间、域名等),可以修改set逻辑,允许传入配置对象:
set(target, prop, options) { let { value, expires, path = "/", domain } = options; const encodedName = encodeURIComponent(prop); const encodedValue = encodeURIComponent(value); let cookieStr = `${encodedName}=${encodedValue}; path=${path}`; if (expires) cookieStr += `; expires=${expires.toUTCString()}`; if (domain) cookieStr += `; domain=${domain}`; document.cookie = cookieStr; return true; } // 使用方式 Cookie.c.something = { value: "hello", expires: new Date(Date.now() + 24 * 60 * 60 * 1000) // 1天后过期 };
内容的提问来源于stack exchange,提问作者stio
相关产品推荐
相关产品推荐

