js判断cookie是否存在
document.cookie是判断个让人又爱又恨的东西。爱它简单,否存恨它太简单——你明明只想看看某个键在不在,判断它却把整个cookie字符串甩你脸上,否存像把整条街的判断快递全堆在门口,你得自己翻找那个写着名字的否存包裹。 判断cookie是判断否存在,最直接的否存办法是`indexOf`。比如查`user_token`: ```javascript if (document.cookie.indexOf('user_token') > -1) { // 存在 } ``` 但这里有个坑。判断`indexOf`是否存子串匹配,`user_token`能匹配到`user_token_expired`,判断也能匹配到`fake_user_token`。否存你查`name`,判断结果`my_name_is_xxx`也通过了。否存这就像你要找叫“王伟”的判断人,结果系统把所有带“伟”字的都算上了。 更稳妥的做法是精确匹配键名。把cookie字符串按`; `拆开,再逐项比对: ```javascript function hasCookie(name) { return document.cookie.split('; ').some(item => { return item.split('=')[0] === name; }); } ``` 这段代码把每个cookie项拆成键值对,只比对等号前的部分。`some`方法一旦找到匹配就返回true,效率也不错。我实际用下来,这种写法在大多数业务场景下够用了。 但等等——你确定“存在”就等于“能用”吗?cookie值可能是空字符串,可能是`"null"`,也可能是`"undefined"`。我见过不少bug,就是后端删cookie时没删干净,留了个空壳,前端判断存在后直接拿去用,结果解析JSON报错。所以更严谨的判断应该带上值校验: ```javascript function hasValidCookie(name) { const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')); return match !== null && match[1] !== '' && match[1] !== 'null'; } ``` 这里用了正则,`(?:^|; )`确保匹配从字符串开头或分号空格后开始,避免误伤`my_user_token`这类前缀相似的键。`([^;]*)`捕获等号后的值,直到遇到分号为止。 不过话说回来,有时候你根本不需要判断cookie存在与否。比如要读取用户登录状态,直接尝试解析值,失败就当作未登录,反而更简洁: ```javascript function getCookieValue(name) { const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)')); return match ? decodeURIComponent(match[1]) : null; } ``` 调用时判断返回值是否为null就行。这比先判断存在、再读取值少了一次字符串扫描,代码也更短。我更喜欢这种风格——把“是否存在”和“值是什么”合并成一个问题。 还有种特殊情况需要留意:HttpOnly cookie。这种cookie设置了`HttpOnly`标志,浏览器端JavaScript根本读不到,`document.cookie`里压根不出现。你判断不存在,但它在请求里确实带着。所以如果判断结果和预期不符,先确认是不是HttpOnly。 最后说个真实案例。之前做一个电商项目,前端判断`cart_id`是否存在来决定显示空购物车还是已有商品。当时用`indexOf`判断,结果cookie里有个`cart_id_old`,导致新用户刚进页面就显示“购物车有1件商品”,实际上那件商品是另一个用户留下的残留数据。后来改成精确匹配键名才解决。从那以后,我写cookie判断都会问一句:这个键名会不会和其他键有前缀重合?值会不会是空字符串或特殊值?虽然多写几行,但省下的排查时间远超代码成本。
-
上一篇
-
下一篇