HTML Web Storage
浅谈 Web 前端 Client side storage。更新参考这篇An Overview of Client-Side Storage。
目前有四种 active 的方式:Cookies,Local Storage,Session Storage,IndexedDB。
Cookies
Cookies 是一种经典地存储简单 string 数据的方式。可以由 server 发给 client,然后 client 保存在本地,下次请求再传回 server。这样 server 可以管理帐户 session,追踪用户信息。它可以由 client 本地设置,传给 server。
以前也用它来存储纯客户端的数据,比如用户偏好。具体操作见 JS BOM 章节 Cookies 部分。
优势:
- 可用于与 server 的通信
- 可设置自动过期时间,不需要手动删除
劣势:
- 存储数据量小(大约4KB多数据)
- 只能存 string
- 潜在安全问题Cookies and security
- 自从 Web Storage API 出来它不再是推荐的客户端存储方法
Local Storage
window.localStorage 是 H5 Web Storage API 之一,区别于 Cookies,存储的数据不会发给 server,可以被同源的每个窗口或标签页共享。
window interface 提供的只读属性,允许获取文档 origin 下的 Storage 对象。
存储的数据不会因为浏览器关闭而删除,如没有干预,将一直有效。
注意:如果用户使用 “无痕/私有/隐私保护” 模式的进行浏览,那么在浏览器关闭后,localStorage 中的值将不会保存。因为使用了这种模式的用户已经明确选择不留痕迹。
操作方法:
const user = { name: 'Vivienne', age: 25 }
// Create
localStorage.setItem('user', JSON.stringify(user));
// Read (Single)
JSON.parse(localStorage.getItem('user'))
// 如果 key 不存在,返回 null
// 也可以使用以下方法 create/read
localStorage.lastname = "Smith";
localStorage['lastname'] = "Smith";
// Update
const updatedUser = { name: 'Vivienne', age: 24 }
localStorage.setItem('user', JSON.stringify(updatedUser));
// Delete
localStorage.removeItem('user');
// 获取所有key名
Object.keys(localStorage)
优势:与 Cookies 对比
- 更简单直观地操作接口
- 更安全(数据不会在网络上传输)
- 存储更多数据(至少5MB)
劣势:
只允许存储 String,但我们可以存储 stringified JSON,实现存储复杂数据。
区别: http 和 https 相同域名下的 localStorage 数据不共享,而 cookie 是共享的。
注意!!!网站通过 http://example.com 加载返回的 local storage 对象与 通过 https://example.com 加载不同。
Session Storage
window.sessionStorage 是 H5 Web Storage API 第二种类型,用法、优劣势、支持性都同 localStorage。区别:数据只为 browser tab session 存储(即数据只在构建它们的窗口或标签内可见)。
补充:
clear()
函数删除存储列表中所有的数据,空的 Storage 对象调用此函数也是安全的,只是不执行任何操作。- 如果用户已关闭了网站的存储,或存储达到其最大的容量,此时设置数据将抛出 QUOTA_EXCEEDED_ERR 错误。
- 只要有同源的 Storage 事件发生(包括 SessionStorage 和 LocalStorage 触发的事件),已注册的所有事件侦听器作为事件处理程序就会接到相应的 Storage 事件。该事件中包含与存储变化有关的信息。如果是新添加的数据,则 oldValue 属性值为 null;如果是被删除的数据,则 newValue 属性值为 null。
- 打开多个相同URL的标签页,每个标签页创建各自的 sessionStorage 对象。关闭对应标签页,会清除该标签页的 sessionStorage 对象。
IndexedDB
IndexedDB 是一个事务型基于 JavaScript 的面向对象数据库,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务。
- 该 API 可以存储结构化克隆算法支持的任何对象。
- 使用键索引实现对数据的高性能搜索。
- 操作是异步执行。
- 遵守同源策略。
优势:
- 可处理更复杂、结构化的数据
- 可拥有多个 databases,每个数据库里可有多个 tables
- 存储更多数据
- 更多交互上的控制
劣势:
相比 Web Storage API 用起来复杂。如果你更喜欢一个简单的 API,可以考虑使用第三方库。
同源策略
目的:保证用户信息的安全,防止恶意网站窃取数据。
协议、主域名、子域名和端口号都相同,则为同源。
有三种行为受到同源策略限制:
- Cookie、LocalStorage 和 IndexedDB 无法读取。
- DOM 无法获得。
- AJAX 请求无法发送。
但一个网站很难掌握所有的资源,因此就需要跨域访问:
-
CORS(Cross-Origin Resource Sharing):允许服务器设置 Access-Control-Allow-Origin 头,允许跨域请求。
主要应用三种场景:简单请求(GET、HEAD、POST,头部字段仅包含Accept、Accept-Language、Content-Language、Content-Type,其中Content-Type的值仅限于这3者之一:application/x-www-form-urlencoded、multipart/form-data、text/plain)、预检请求(PUT、DELETE、OPTIONS等,可以自定义头部,向服务器发送application/json格式的数据)、认证请求。 预检请求:在正式请求之前,客户端发送一个 OPTIONS 请求,询问服务器是否允许跨域请求。服务器成功响应后,返回 Access-Control-Allow-Methods 头,客户端再发送实际请求。
-
JSONP(JSON with Padding):通过动态创建 script 标签,请求跨域资源,并在请求成功后执行回调函数。参看JavaScript JSON章节。