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

时间:2022-05-18 08:42:17

一、在线状态检测

开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器。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。

读javascript高级程序设计17-在线检测,cookie,子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

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

  1. 读javascript高级程序设计00-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  2. 读javascript高级程序设计-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

  3. 读javascript高级程序设计08-引用类型之Global、Math、String

    一.Global 所有在全局作用域定义的属性和方法,都属于Global对象. 1.URI编码: encodeURI():主要用于对整个URI编码.它不会对本身属于URI的特殊字符进行编码. encod ...

  4. 读javascript高级程序设计09-BOM

    一.window 1.在全局作用域中定义的变量和函数会被归在window对象. var a=1,b=2; function add(a,b){ return a+b; } console.log(wi ...

  5. 读javascript高级程序设计10-DOM

    一.节点关系 元素的childNodes属性来表示其所有子节点,它是一个NodeList对象,会随着DOM结构的变化动态变化. hasChildNodes():是否有子节点. var headline ...

  6. 读javascript高级程序设计12-HTML5脚本编程

    一.跨文档消息传递(XDM) 1.发送消息 postMessage(msg,domain)用于发送跨文档消息.第一个参数是要传递的消息内容,第二个参数表示接收方来自哪个域.第二个参数有助于提高安全性, ...

  7. 读javascript高级程序设计14-错误处理与调试

    一  错误类型 ECMA规定了常见的7种错误类型: Error: 基类型.其他常见的错误类型都继承自该类型,一般供开发人员抛出自定义错误. EvalError:该类型会在eval()函数使用异常时被抛 ...

  8. 读javascript高级程序设计15-Ajax&comma;CORS&comma;JSONP&comma;Img Ping

    平时用惯了jQuery.ajax之类的方法,却时常忽略了它背后的实现,本文是学习了AJAX基础及几种跨域解决方案之后的一些收获. 一.AJAX——XMLHttpRequest 谈起Ajax我们都很熟悉 ...

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

    虽然Object构造函数或者对象字面量都可以用来创建单个对象,但是缺点非常明显:使用同一接口创建很多对象,会产生大量重复代码. 工厂模式  1 function CreatePerson(name,a ...

随机推荐

  1. TDD原则

    TDD 介绍 测试驱动开发,或者叫 TDD,是一个敏捷方法,通过确保在代码是先前手动编写测试用 例,用测试来驱动开发,从而翻转开发生命周期(它不只是作为一种校验工具). TDD 的原则很简单的: 只有 ...

  2. Android签名总结

    signapk.jar与eclipse export插件默认赋予程序一个DEBUG权限的签名 signapk.jar包含有系统权限(system api, permission),而eclipse e ...

  3. meta-analysis 到底是什么个意思类?

    背景 科学研究应建立于许多实验结果的重复之上,除了少数新发现外,单个实验结果很难对科学的发展作出极为显著的贡献.所以为了阐明某一主题,在许多科学领域有众多研究者在对不同的实验对象或对同一对象在不同的实 ...

  4. 查看mssql的锁

    USE [master]GO /****** Object: StoredProcedure [dbo].[sp_who_lock] Script Date: 10/02/2014 06:18:19 ...

  5. COJ978 WZJ的数据结构(负二十二)

    试题描述 输入两个正整数N.K,以及N个整数Ai,求第K小数. 输入 第一行为两个正整数N.K.第二行为N个正整数Ai. 输出 输出第K小数. 输入示例 5 41 2 3 3 5 输出示例 3 其他说 ...

  6. 使用微信JSSDK自定义分享内容

    微信在6.0.2.58版本以后开始使用新的api,在Android系统中不能用以前的代码来自定义分享内容了. 现在自定义内容的方法走的是公众号的一套流程 1获取access_token 2得到toke ...

  7. &period;net 中连接mysql

    1. 下载mysql驱动.里面包含需要连接mysql的dll.mysql-connector-net    地址:http://dev.mysql.com/downloads/file/?id=463 ...

  8. 2018-05-01T00&colon;00&colon;00&period;000&plus;08&colon;00转2018-05-01 00&colon;00&colon;00

    /** * 2018-05-01T00:00:00.000+08:00转2018-05-01 00:00:00 * @param oldDateStr * @return * @throws Pars ...

  9. What is the difference between WinRT&comma; UWP and WPF&quest;

    在学习UWP的过程中确实有这个迷惑,在此分享一下. UWP (Universal Windows platform), Metro and WinRT are all result of Micros ...

  10. 线程同步 –AutoResetEvent和ManualResetEvent

    上一篇介绍了通过lock关键字和Monitor类型进行线程同步,本篇中就介绍一下通过同步句柄进行线程同步. 在Windows系统中,可以使用内核对象进行线程同步,内核对象由系统创建并维护.内核对象为内 ...