读javascript高级程序设计17-在线检测,cookie,子cookie

一、在线状态检测

开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器。html5提供了检测在线状态的方法:navigator.onLine和online/offline事件。

1.navigator.onLine属性

表示当前的网络状态是否在线,true表示在线,false表示离线。当网络状态变化时,该属性也会随之变化。

2.online和offline事件

HTML5提供了这两个事件,会在网络状态变化时触发。online在网络由离线变为在线时触发;offline在网络由在线变为离线时触发。

<p>You are currently: <span id="status"><script>document.write(navigator.onLine ? "在线" : "离线");</script></span></p>
    <p>切换脱机状态,看看效果</p>
    <script>
        EventUtil.addHandler(window, "online", function(){
            document.getElementById("status").innerHTML = "在线";
        });
        EventUtil.addHandler(window, "offline", function(){
            document.getElementById("status").innerHTML = "离线";
        });
    </script>

二、cookie

1.cookie构成:

  • 名称:cookie的名称必须是经过URL编码后的字符串。虽然它是不区分大小写的,但是实际应用时建议把它当作区分大小写来使用。
  • 值:cookie中字符串值,也必须是经过URI编码的字符串。
  • 域:表示cookie对于哪个域有效。
  • 路径:cookie是针对域中的哪个目录生效。
  • 失效时间:表示cookie失效时间的时间戳,它是GMT格式的日期。将该事件设置小于当前时,就相当于删除了cookie。
  • 安全标识:指定该标识后,只有使用SSL请求连接的时候cookie才会发送到服务器。secure标识是cookie中唯一一个非键值对的部分,它只包含一个secure单词。

2.cookie读写删除操作

在JavaScript中可以通过document.cookie可以读取当前域名下的cookie,是用分号隔开的键值对构成的字符串。类似于name=aa;age=15;

注意所有的键值对名称和值都是经过encodeURIComponent()编码的,使用时要进行解码。

当给document.cookie赋值时,不会直接覆盖现有的cookie,而是会追加一个新的cookie。例如:

document.cookie="a=1";//执行后会看到新增了一个cookie。

常用的cookie读写删除方法:

var CookieUtil = {
//根据key读取cookie
    get: function (name){
         //注意对键编码
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null,
            cookieEnd;
        //找到cookie键
        if (cookieStart > -1){
             //键后面第一个分号位置
            cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == -1){
                cookieEnd = document.cookie.length;
            }
            //cookie值解码
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
        }
        return cookieValue;
    },
    //设置cookie
    set: function (name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        //失效时间,GMT时间格式
        if (expires instanceof Date) {
            cookieText += "; expires=" + expires.toGMTString();
        }
        if (path) {
            cookieText += "; path=" + path;
        }
        if (domain) {
            cookieText += "; domain=" + domain;
        }
        if (secure) {
            cookieText += "; secure";
        }
        document.cookie = cookieText;
    },
    //删除cookie,保持相同的键、域、路径、安全选项,然后设置失效时间即可
    unset: function (name, path, domain, secure){
        this.set(name, "", new Date(0), path, domain, secure);
    }
};

实例:“不再提示”

<p id="know">友情提示区域1 <a href="javascript:void(0)" target="_self" id="btn-know">不再提示</a></p>
    <input type="button" value="清除cookie" id="delete-btn" />
    <script type="text/javascript">
         var cookiekey="知道了";
        EventUtil.addHandler(window, "load", function(){
            var know1 = CookieUtil.get(cookiekey);
            if(know1){
                 document.getElementById("know").style.display="none";
                 }
            EventUtil.addHandler(document.getElementById("delete-btn"), "click", function(){
                CookieUtil.unset(cookiekey);
            })
        });
        EventUtil.addHandler(document.getElementById("btn-know"),"click",function(){
             CookieUtil.set(cookiekey, "1");
             document.getElementById("know").style.display="none";
             });
    </script>

3.子cookie

有时站点需要记录多个cookie,比如多块功能区域都有气泡提示,点击“不再提示”后取消提醒,此时每个区域都需要记录一个很简单的cookie。由于浏览器cookie数量是有限制的,为了减少cookie数量可以使用子cookie的方式。在一个cookie值中使用类似查询字符串的格式可以存储多组键值对,这样就不必每个键值对都占用一个cookie了。子cookie值举例:

iknow=know0=1&know1=1

①获取所有子cookie并将它放在一个对象中返回,对象的属性名为子cookie名称,对象的属性值为子cookie的值。

getAll: function(name){
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null,
            cookieEnd,
            subCookies,
            i,
            parts,
            result = {};
        if (cookieStart > -1){
            cookieEnd = document.cookie.indexOf(";", cookieStart)
            if (cookieEnd == -1){
                cookieEnd = document.cookie.length;
            }
            //取出cookie字符串值
            cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd);
            if (cookieValue.length > 0){
                   //用&将cookie值分隔成数组
                subCookies = cookieValue.split("&");
                for (i=0, len=subCookies.length; i < len; i++){
                       //等号分隔出键值对
                    parts = subCookies[i].split("=");
                    //将解码后的兼职对分别作为属性名称和属性值赋给对象
                    result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
                }
                return result;
            }
        }
        return null;
    }

②get()获取单个子cookie。

get: function (name, subName){
         //获取所有子cookie
        var subCookies = this.getAll(name);
        if (subCookies){
             //从属性中获取单个子cookie
            return subCookies[subName];
        } else {
            return null;
        }
    }

③setAll设置整个cookie

setAll: function(name, subcookies, expires, path, domain, secure){
        var cookieText = encodeURIComponent(name) + "=",
            subcookieParts = new Array(),
            subName;
        //遍历子cookie对象的属性
        for (subName in subcookies){
             //要先检测属性名
            if (subName.length > 0 && subcookies.hasOwnProperty(subName)){
                 //属性名和属性值编码后=连接为字符串,并放到数组中
                subcookieParts.push(encodeURIComponent(subName) + "=" + encodeURIComponent(subcookies[subName]));
            }
        }
        if (subcookieParts.length > 0){
             //用&连接子cookie串
            cookieText += subcookieParts.join("&");
            if (expires instanceof Date) {
                cookieText += "; expires=" + expires.toGMTString();
            }
            if (path) {
                cookieText += "; path=" + path;
            }
            if (domain) {
                cookieText += "; domain=" + domain;
            }
            if (secure) {
                cookieText += "; secure";
            }
        } else {
            cookieText += "; expires=" + (new Date(0)).toGMTString();
        }
        //设置整个cookie
        document.cookie = cookieText;
    }

④set设置单个子cookie

    set: function (name, subName, value, expires, path, domain, secure) {
        //获取当前cookie对象
        var subcookies = this.getAll(name) || {};
        //单个cookie对应的属性替换
        subcookies[subName] = value;
        //重新设置cookie
        this.setAll(name, subcookies, expires, path, domain, secure);
    }

⑤删除cookie

删除整个cookie, 将失效时间设置为过期日期即可。

unsetAll: function(name, path, domain, secure){
        this.setAll(name, null, new Date(0), path, domain, secure);
    }

删除单个子cookie,需要先获取所有子cookie对象,然后删除子cookie对应的属性,最后再将子cookie对象重新设置回去。

unset: function (name, subName, path, domain, secure){
         //获取当前cookie对象
        var subcookies = this.getAll(name);
        if (subcookies){
             //删除子cookie对应的属性
            delete subcookies[subName];
          //重新设置cookie
            this.setAll(name, subcookies, null, path, domain, secure);
        }
    }

⑥调用实例:多个气泡提示区域,“不再提示”功能cookie记录在同一个cookie中。

<p id="know0">友情提示区域1 <a href="javascript:void(0)" target="_self" id="btn-know0">不再提示</a></p>
    <p id="know1">友情提示区域2 <a href="javascript:void(0)" target="_self" id="btn-know1">不再提示</a></p>
    <input type="button" value="清除cookie" id="delete-btn" />
    <script type="text/javascript">
var cookiekey = ‘iknow‘,
key0 = ‘know0‘,
key1 = ‘know1‘;
EventUtil.addHandler(window, ‘load‘, function () {
  var know0 = SubCookieUtil.get(cookiekey, key0);
  if (know0) {
    document.getElementById(‘know0‘).style.display = ‘none‘;
  }
  var know1 = SubCookieUtil.get(cookiekey, key1);
  if (know1) {
    document.getElementById(‘know1‘).style.display = ‘none‘;
  }
  EventUtil.addHandler(document.getElementById(‘delete-btn‘), ‘click‘, function () {
    SubCookieUtil.unset(cookiekey, key0);
    SubCookieUtil.unset(cookiekey, key1);
  })
  EventUtil.addHandler(document.getElementById(‘btn-know0‘), ‘click‘, function () {
    SubCookieUtil.set(cookiekey, key0, 1);
    document.getElementById(‘know0‘).style.display = ‘none‘;
  });
  EventUtil.addHandler(document.getElementById(‘btn-know1‘), ‘click‘, function () {
    SubCookieUtil.set(cookiekey, key1, 1);
    document.getElementById(‘know1‘).style.display = ‘none‘;
  });
});
    </script>

注意:cookie不能用来存储大量数据,也不能存储敏感数据。

附:cookie.rar

时间: 2024-11-05 17:31:22

读javascript高级程序设计17-在线检测,cookie,子cookie的相关文章

读javascript高级程序设计15-Ajax,CORS,JSONP,Img Ping

平时用惯了jQuery.ajax之类的方法,却时常忽略了它背后的实现,本文是学习了AJAX基础及几种跨域解决方案之后的一些收获. 一.AJAX——XMLHttpRequest 谈起Ajax我们都很熟悉,它的核心对象是XMLHttpRequest(简称XHR). 1.创建对象: 在ie7及以上版本支持原生的写法创建该对象. var xhr=new XMLHttpRequest(); 2.发送请求: open(type,url,isasync):第一个参数是请求类型(get,post),第二个参数是

[已读]JavaScript高级程序设计(第3版)

从去年开始看,因为太长,总是没有办法一口气把它看完,再加上它与第二版大部分一致,读起来兴致会更缺一点. 与第二版相比,它最大的改变就是增加了很多html5的内容,譬如:Object对象的一些新东西,数据属性.访问器属性及相应的一些方法;比如它对跨域常见方法的比较和总结:postMessage,IE8的XDR,升级的XHR,jsonp跨域原理,单向的图片ping;又比如对数据推送的一些介绍,长轮询和http流是什么样子,单向的SSE和双向的Web Socket的详细介绍和比较. PS,关于SSE,

读Javascript高级程序设计第三版第六章面向对象设计--创建对象

虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码. 工厂模式  1 function CreatePerson(name,age,job){ 2         var o=new Object(); 3         o.name=name; 4         o.age=age; 5         o.job=job; 6         o.sayName=function(){ 7            

JavaScript高级程序设计17.pdf

导航和打开窗口 使用window.open()方法可以导航到一个特定的URL也可以打开一个新的浏览器窗口,接收4个参数:要加载的URL.窗口目标.特性字符串和一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值.通常只需要传递第一个参数,最后一个参数只在不打开新窗口的情况下使用,如果传递的第二个参数,该参数是已有的窗口或者框架的名称,那么就会在该窗口加载第一个参数指定的URL //等同于<a href="http://www.baidu.com" target="

JavaScript高级程序设计之客户端检测

浏览器检测,是个很让人头痛但又必须要考虑的一个问题.毕竟市面上的浏览器厂商众多,虽然有些标准化的东西约束着他们,但是有些东西,他们还是各自按自己的意愿来.这其中以IE浏览器最为突出,它几乎可以被称之为万恶之源. 浏览器检测的方法有很多,这里介绍的可能并不是全部,但基本上都是比较常用的方法.下边我就来详细介绍一下高设上提供的浏览器检测的方法. 能力检测 能力检测比较简单,就是判断浏览器支不支持这个方法.例:if(Object.assign){ ...... }.这种方法最简单,也最常用,但缺点也很

读javascript高级程序设计16-几条函数小技巧

内容概要 作用域安全的构造函数 惰性载入函数 函数绑定 函数节流 一.作用域安全的构造函数 我们知道,当使用new操作符调用构造函数时,构造函数内部的this会指向新创建对象的实例. function Person(name){ this.name=name; } var p=new Person('peter'); console.log(p.name);//结果:perter 但是,如果没有使用new操作符,而是将构造函数当作普通函数调用时,this会指向window对象. var p1=P

javascript高级程序设计 第九章-- 客户端检测

javascript高级程序设计 第九章-- 客户端检测 客户端检测是javascript开发中最具争议的一个话题,由于浏览器间存在差别,通常需要根据不同浏览器的能力分别编写不同的代码.有下列常使用的客户端检测方法:能力检测:在编写代码之前先检测特定浏览器的能力.例如,脚本在调用某个函数之前,可能要先检测该函数是否存在.这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上.能力检测无法精确地检测特定的浏览器和版本.怪癖检测:怪癖实际上是浏览器中存

JavaScript高级程序设计(第三版)学习笔记20、21、23章

第20章,JSON JSON(JavaScript Object Notation,JavaScript对象表示法),是JavaScript的一个严格的子集. JSON可表示一下三种类型值: 简单值:字符串,数值,布尔值,null,不支持js特殊值:undefined 对象:一组无序的键值对 数组:一组有序的值的列表 不支持变量,函数或对象实例 注:JSON的字符串必须使用双引号,这是与JavaScript字符串最大的区别 对象 { "name":"Nicholas"

《JavaScript 高级程序设计》

因为曾经在高中买来<C Primer Plus>和大学买来的<Clean Code>(挑战自己买的英文版的结果就啃了一点)给我一种经典的书都特别厚的一本就够读大半年的感觉.加上刚上大学图便宜买的有关做网站的旧书(应该是 Table 布局和 Dreamweaver 比较火的时代的书,这些书倒是很薄)让我一度认为做网页不就是 table 然后 tr.td 什么的套呗,高大上点不就是 div+CSS 嘛有什么大不了,给我设计好什么网页不都 ok 能做出来么?这种感觉.然后看网络课程,在网