当前位置: 首页 > news >正文

记一次js操作cookie的坑!

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    需求:在网站首页加了一个广告模态框,要求每天第一次访问时弹出,此后当天不再弹。

    网站上线的当天晚上,大BOSS临时加的一个小需求,当时感觉没什么困难的,几分钟的事情,模态框和cookie操作都是封装好的工具方法,只要将广告图片加上,再存个弹出标识cookie,设置过期时间24小时就ok。然而,实际操作起来,效果却不理想。

    我们项目用的是angularjs 1.3的框架,说这个问题之前,不得不提我做登录功能时,遇到的另一个cookie问题。当时操作cookie用的是$cookieStore。但是他好像不兼容IE8,当时用他来做登录功能时,发现页面不能跳转,一跳转页面cookie就会消失,在本页面即使刷新也能读取到cookie。

    首先百度查了又查,有的说是IE8设置问题,有的说是用法问题,有的说是兼容问题,反正我都试了,最终只能归咎于兼容问题。同时可以肯定的,这应该是和cookie的作用域或是路径有关系,但是我又没法查看IE8下面cookie的详细信息,而$cookieStore又无法手动设置作用域和路径。这时,我想起以前用过用js封装过cookie工具方法,确定是可以兼容IE8的。于是我就直接拿过来用了,最后测试IE8,果然问题没了。此外我还多测了一下,利用js的方法,我不设置作用域,问题任然存在。

    再次回到本问题,此次我用的仍是前面的用到的js方法,我信誓旦旦应该不存在什么问题的,但偏偏问题又来了。这次的情况是这样的,在本页面设置cookie后,跳转页面也能获取到,但是一刷新cookie我获取到的值就为空字符串。当时简直傻眼了,因为晚上还要上线,我前面还和经理保证过没问题的,结果又遇到坑了,我那个急啊,因为我原本没想当过会出问题的地方,居然又出了一个无脑的问题,搞的我一脸萌币。而且又急着上线,搞的我一点解决思路都没得;但是没法只能硬着头皮上了。

    首先还是百度,百度上也有类似的问题,但是很少,而且都没有确切的回答(估计是因为问题太SB);终于,翻到了一个比较靠谱的回答,大概的意思是这样的:cookie域名设置必须要是域名,IP地址无效。靠,我顿时恍然大悟(此时我完全忘了以前的登录功能就是用IP做的),于是又用host文件映射IP和域名,最后一测,果然有效,我简直要笑了,不要这么轻松好不好~

    于是,我兴冲冲的跑去跟经理汇报了,经理一听立刻就把网站发到了公测环境;然后经理一打开网站就看到了弹窗,然后刷新,弹窗又出来了,再然后就问我,这弹窗为什么还一直弹啊,我当时就猜到他会这么问了,然后就把网上的答案给他了,我说,因为cookie设置需要用具体的域名,ip设置无效,放到线上就好了(此时仍未发现问题)~见鬼了,当天晚上因为测试请假先走了,这个问题最后到上线都没人发现。

    终于,网站上线了,我又兴冲冲打开线上的网站来验证,一打开,广告出来了,然后刷新,他 妹 的又出来了,我靠,当时我的脸顿时感到火辣辣的。但是没办法问题还在啊,我一边忍着不哭一边慌忙的再次找原因,但是经过这么一搞,我又一点思路都没了。

    之后因为上线时已经是晚上9点30了,经理就过来跟我们说,网站上线了,大问题没有,但是那个弹窗还是老弹(当时真想钻地缝),今晚不早了就先下班吧~~~然后同事们就迅速的关机走人了。当时我真不想走的,因为真的是太尴尬了,但是留下来又不知道要搞到什么时候,关键是公司又没人了,好吧,先走吧,明天再说......于是,我也关机走人。

    到家了,以前都是很兴奋的,搞不好还会先撸一把再睡,但是那天晚上终于没心情了,念念不忘刚才的问题,但是怎么也想不通。于是,我又打开电脑、打开google、打开线上的网站,打开控制台......然后让自己平静下,再次从头开始排查,首先我发现cookie设置是成功的,从google上看到cookie的过期时间、作用域和路径都没问题,于是排除cookie本身的问题。其次,是使用的工具方法,用的是以前的老方法,因此问题应该不在方法上。

    最后,我发现,当我刷新页面时,cookie也跟着刷新;这地方就很奇怪了,因为cookie的过期时间是24小时,怎么可能一刷新页面,cookie就像刷新一样呢?幸好在家里人比较冷静,稍微思考下就想到一种可能性,那就是在前面的js中,可能在某些地方对cookie做了清除,有了这个想法,我马上进行了验证,果然在验证登录状态的方法中利用了清除cookie的操作,当初这么做是为了检测到未登录时,避免残留cookie对后面产生影响,就偷懒用了清空所有cookie,这就导致不登录时cookie永远都会先清后存。

    总结:这是一个自己坑自己的故事,我想在实际开发中这类问题应该会经常遇到,只能更加细心一点,让自己少点坑!

    附兼容IE的cookie操作方法:

var $tools= {
    //清楚所有cookie,或清除指定名称的cookie
    clearAll: function (me){
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i];
            var eqPos = cookie.indexOf("=");
            var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
            if (!!me){
                if (me === $.trim(name)){
                    document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
                }
            }else{
                document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
            }
        }
        if(cookies.length > 0)
        {
            for (var i = 0; i < cookies.length; i++) {
                var cookie = cookies[i];
                var eqPos = cookie.indexOf("=");
                var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
                var domain = location.host.substr(location.host.indexOf('.'));
                if (!!me){
                    if (me === $.trim(name)){
                        document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=" + domain;
                    }
                }else {
                    document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=" + domain;
                }
            }
        }
    },

    //保存cookie
    setCookie: function (name, value, hour, domain){
        if (!!domain && domain.indexOf('www.') != -1){
            domain= domain.substring(4);
        }
        var curCookie = name + "=" + encodeURIComponent(value) +";";
        if(0 != hour){
            var date = new Date();
            date.setTime(date.getTime() + hour * 3600 * 1000);
            var expires = date.toGMTString();
            curCookie += "expires=" + expires +";";
        }
        curCookie += "path=/";
        if(""!=domain){
            curCookie += ";domain="+domain;
        }
        document.cookie = curCookie;
    },

    //获得cookie
    getCookie: function (name){
        var dc = document.cookie;
        var prefix = name + "=";
        var begin = dc.indexOf("; " + prefix);
        if (begin == -1){
            begin = dc.indexOf(prefix);
            if (begin != 0) return "";
        }else{
            begin += 2;
        }
        var end = document.cookie.indexOf(";", begin);
        if (end == -1){
            end = dc.length;
        }
        return unescape(dc.substring(begin + prefix.length, end));
    }
}

 

转载于:https://my.oschina.net/trueloveforever/blog/1563322

相关文章:

  • apache日志轮询cronolog安装配置
  • 网站被用户喜爱的秘密 :挖掘关键词背后的用户需求
  • 关于虚拟目录继承根Web.Config的问题解决办法
  • 初识JSON
  • 初次使用EasyUI框架插件遇到的问题及总结
  • linux命令入门
  • Tomcat/Memcached实现会话保持(SessionServer)
  • CloudStack 4.4+KVM之通过ISO文件创建CentOS虚拟机
  • MS Project学习笔记一:安装
  • php变量处理函数总结
  • centos6安装django-1.8.11
  • 【iOS-Cocos2d游戏开发之七】添加/删除系统组件,并解决View设置透明会影响View中的其他组件的问题!...
  • 多使用调用堆栈调试VC++代码
  • Hyper-V 2016 系列教程53 What's new in Hyper-V on Windows Server 2016
  • 一个不错的linux学习资料下载的网址
  • 《Java编程思想》读书笔记-对象导论
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • Android框架之Volley
  • extjs4学习之配置
  • gf框架之分页模块(五) - 自定义分页
  • Java基本数据类型之Number
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • PHP面试之三:MySQL数据库
  • Python进阶细节
  • springMvc学习笔记(2)
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 爱情 北京女病人
  • 订阅Forge Viewer所有的事件
  • 缓存与缓冲
  • 深入浅出Node.js
  • 算法-图和图算法
  • 运行时添加log4j2的appender
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • #HarmonyOS:Web组件的使用
  • ( 10 )MySQL中的外键
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (编译到47%失败)to be deleted
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)C#调用WebService 基础
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • .gitignore文件—git忽略文件
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET面试题(二)
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .pyc文件是什么?
  • @Responsebody与@RequestBody
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)