JavaScript高级程序设计(4)
第25章 客户端存储
### 25.1 cookie 751 ##### 25.1.1 限制 - > 只要遵守以下大致的限制,就不会在任何浏览器中碰到问题: > > - 不超过 300 个 cookie; > - 每个 cookie 不超过 4096 字节; > - 每个域不超过 20 个 cookie; > - 每个域不超过 81920 字节。 > - 每个域能设置的 cookie 总数也是受限的,但不同浏览器的限制不同:edge 50个,firefox 150个,opera 180个,safari和chrome没有硬性限制。如果 cookie 总数超过了单个域的上限,浏览器就会删除之前设置的 cookie。 ##### 25.1.2 cookie 的构成 - > cookie 在浏览器中是由以下参数构成的:名称、值、域、路径、过期时间、安全标志。 > > ```javascript > Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com > > Set-Cookie: name=value; domain=.wrox.com; path=/; secure > ``` ##### 25.1.3 JavaScript 中的 cookie - > document.cookie 返回包含页面中所有有效 cookie 的字符串(根据域、路径、过期时间和安全设置),以分号分隔,所有名和值都是 URL 编码的,因此必须使用 decodeURIComponent()解码。 > > document.cookie 在设置值时,可以通过 document.cookie 属性设置新的 cookie 字符串。这个字符串在被解析后会添加到原有 cookie 中。 > > ```javascript > class CookieUtil { > static get(name) { > let cookieName = `${encodeURIComponent(name)}=`, > cookieStart = document.cookie.indexOf(cookieName), > cookieValue = null; > if (cookieStart > -1){ > let cookieEnd = document.cookie.indexOf(";", cookieStart); > if (cookieEnd == -1){ > cookieEnd = document.cookie.length; > } > cookieValue = decodeURIComponent(document.cookie.substring(cookieStart > + cookieName.length, cookieEnd)); > } > return cookieValue; > } > static set(name, value, expires, path, domain, secure) { > let cookieText = > `${encodeURIComponent(name)}=${encodeURIComponent(value)}` > 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; > } > static unset(name, path, domain, secure) { > CookieUtil.set(name, "", new Date(0), path, domain, secure); > } > }; > > // 设置 cookie > CookieUtil.set("name", "Nicholas"); > // 读取 cookie > alert(CookieUtil.get("name")); // "Nicholas" > // 删除 cookie > CookieUtil.unset("name"); > // 设置有路径、域和过期时间的 cookie > CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com", new Date("January 1, 2010")); > // 删除刚刚设置的 cookie > CookieUtil.unset("name", "/books/projs/", "www.wrox.com"); > // 设置安全 cookie > CookieUtil.set("name", "Nicholas", null, null, null, true); > ``` ##### 25.1.4 子 cookie - > 为绕过浏览器对每个域 cookie 数的限制,有些开发者提出了子 cookie 的概念。子 cookie 是在单个cookie 存储的小块数据,本质上是使用 cookie 的值在单个 cookie 中存储多个名/值对。 ##### 25.1.5 使用 cookie 的注意事项 - > - 还有一种叫作 HTTP-only 的 cookie。HTTP-only 可以在浏览器设置,也可以在服务器设置,但只能在服务器上读取,这是因为 JavaScript 无法取得这种 cookie 的值。 > - 不要在 cookie 中存储重要或敏感的信息。cookie 数据不是保存在安全的环境中,因此任何人都可能获得。应该避免把信用卡号或个人地址等信息保存在 cookie 中。 > - 保存的 cookie 越大,请求完成的时间就越长。最好还是尽可能只通过 cookie 保存必要信息,以避免性能问题。 > - 对 cookie 的限制及其特性决定了 cookie 并不是存储大量数据的理想方式。 ### 25.2 Web Storage 759 > Web Storage 的目的是解决通过客户端存储不需要频繁发送回服务器的数据时使用 cookie 的问题。 ##### 25.2.1 **Storage** 类型 - > Storage 类型用于保存名/值对数据,直至存储空间上限(由浏览器决定),有以下方法: > > - clear():删除所有值;不在 Firefox 中实现。 > - getItem(*name*):取得给定 *name* 的值。 > - key(*index*):取得给定数值位置的名称。 > - removeItem(*name*):删除给定 *name* 的名/值对。 > - setItem(*name*, *value*):设置给定 *name* 的值。 ##### 25.2.2 **sessionStorage** 对象 - > sessionStorage 对象只存储会话数据,这意味着数据只会存储到浏览器关闭。存储在 sessionStorage 中的数据不受页面刷新影响,可以在浏览器崩溃并重启后恢复。 > > 所有现代浏览器在实现存储写入时都使用了同步阻塞方式,因此数据会被立即提交到存储。通过 Web Storage 写入的任何数据都可以立即被读取。 > > ```javascript > // 使用方法存储数据 > sessionStorage.setItem("name", "Nicholas"); > // 使用属性存储数据 > sessionStorage.book = "Professional JavaScript"; > > // 使用方法取得数据 > let name = sessionStorage.getItem("name"); > // 使用属性取得数据 > let book = sessionStorage.book; > > //可以结合 sessionStorage 的 length 属性和 key()方法遍历所有的值: > for (let i = 0, len = sessionStorage.length; i < len; i++){ > let key = sessionStorage.key(i); > let value = sessionStorage.getItem(key); > alert(`${key}=`${value}`); > } > ``` ##### 25.2.3 **localStorage** 对象 - > 要访问同一个 localStorage 对象,页面必须来自同一个域(子域不可以)、在相同的端口上使用相同的协议。 > > localStorage 是 Storage 的实例,所以可以像使用 sessionStorage 一样使用localStorage。 > > 两种存储方法的区别在于,存储在 localStorage 中的数据会保留到通过 JavaScript 删除或者用户清除浏览器缓存。localStorage 数据不受页面刷新影响,也不会因关闭窗口、标签页或重新启动浏览器而丢失。 > > ```javascript > // 使用方法存储数据 > localStorage.setItem("name", "Nicholas"); > // 使用属性存储数据 > localStorage.book = "Professional JavaScript"; > // 使用方法取得数据 > let name = localStorage.getItem("name"); > // 使用属性取得数据 > let book = localStorage.book; > ``` ##### 25.2.4 存储事件 - > 每当 Storage 对象发生变化时,都会在文档上触发 storage 事件。使用属性或 setItem()设置值、使用 delete 或 removeItem()删除值,以及每次调用 clear()时都会触发这个事件。 > > ```javascript > window.addEventListener("storage", (event) => alert('Storage changed for ${event.domain}')); > ``` ##### 25.2.5 限制 - > 不同浏览器给 localStorage 和 sessionStorage 设置了不同的空间限制,但大多数会限制为每个源 5MB。 ### 25.3 IndexedDB 762 ##### 25.3.1 数据库 - > ```javascript > let db, request, version = 1; > request = indexedDB.open("admin", version); > request.onerror = (event) => { > alert(`Failed to open: ${event.target.errorCode}`); > } > request.onsuccess = (event) => { > db = event.target.result; > }; > ``` ##### 25.3.2 对象存储 - > ```javascript > let user = { > username: "007", > firstName: "James", > lastName: "Bond", > password: "foo" > }; > request.onupgradeneeded = (event) => { > const db = event.target.result; > // 如果存在则删除当前 objectStore。测试的时候可以这样做 > if (db.objectStoreNames.contains("users")) { > db.deleteObjectStore("users"); > } > db.createObjectStore("users", { keyPath: "username" }); > }; > // 创建对象存储时必须指定一个唯一键。这里第二个参数的 keyPath 属性表示应该用作键的存储对象的属性名。 > ``` ##### 25.3.3 事务 ##### 25.3.4 插入对象 ##### 25.3.5 通过游标查询 ##### 25.3.7 设置游标方向 ##### 25.3.8 索引 ##### 25.3.9 并发问题 - > 第一次打开数据库时,添加 onversionchange 事件处理程序非常重要。另一个同源标签页将数据库打开到新版本时,将执行此回调。对这个事件最好的回应是立即关闭数据库,以便完成版本升级。 > > ```javascript > request.onsuccess = (event) => { > database = event.target.result; > database.onversionchange = () => database.close(); > }; > ``` ##### 25.3.10 限制 - > IndexedDB 数据库是与页面源(协议、域和端口)绑定的,因此信息不能跨域共享。这意味着 www.wrox.com 和 p2p.wrox.com 会对应不同的数据存储。 > > 其次,每个源都有可以存储的空间限制。当前 Firefox 的限制是每个源 50MB,而 Chrome 是 5MB。移动版 Firefox 有 5MB 限制,如果用度超出配额则会请求用户许可。 > > Firefox 还有一个限制——本地文本不能访问 IndexedDB 数据库。Chrome 没有这个限制。因此在本地运行本书示例时,要使用 Chrome。
顶部
收展
底部
[TOC]
目录
第1章 JavaScript简介
第2章 在 HTML中使用JavaScript
第3章 语言基础(1)语法变量
第3章 语言基础(2)数据类型
第3章 语言基础(3)操作符
第3章 语言基础(4)语句
第4章 变量、作用域与内存
第5章 基本引用类型
第6章 集合引用类型
第7章 迭代器与生成器
第8 章对象、类与面向对象编程
第9章 代理与反射
第10章 函数
第11章 期约与异步函数
第12章 BOM
第13章 客户端检测
第14章 DOM
第15章 DOM 扩展
第16章 DOM2 和 DOM3
第17章 事件
第18章 动画与 Canvas 图形
第19章 表单脚本
第20章 JavaScript API
第21章 错误处理与调试
第22章 处理 XML
第23章 JSON
第24章 网络请求与远程资源
第25章 客户端存储
第26章 模块
第27章 工作者线程
第28章 最佳实践
相关推荐
WebSocket