前端本地存储
# cookie
Cookie 定义:
中文名称为'小型文本文件'或'小甜饼',指某些网站为了辨识用户身份而存储在用户本地终端上的数据(通常 name 和 value 经过编码)。
Cookie 组成:Cookie: [name][value][domain][path][expires][httponly][secure]
通常通过 JS 设置 Cookie 为以下形式。当然,最好的方式是通过一个函数来设置。
document.cookie = 'name=kk; domain=localhost; path=/; expires= Mon Nov 06 2017 01:32:07 GMT+0800 (CST)'
- Cookie 大小:
大多数浏览器 Cookie 默认大小为 4kb。超过的部分会被截断掉。
- Cookie 分类:
根据 Cookie 中的 expires 字段,可以将 Cookie 分为本地(持久化)Cookie 和内存(非持久化)Cookie。
当 expires 没有设置时,实际上就相当于一个内存 Cookie。浏览器关闭之后就消失了。同时,在当前浏览器下,打开多个页面仍然可以访问到 Cookie 消息。也就是说,如果浏览器不关掉的情况下都会发送 Cookie。
当 expires 设置一个未来的时间,那么就是一个本地 Cookie。此时会将 Cookie 存入到操作系统本地,待过期时间到了才会消失。
因此根据 expires 字段,可以利用 Cookie 做用户登录认证、购物车信息存储等功能。
- Cookie 用途:
当登录一个网站的时候。
- 客户端会将登录的账号和密码发送到服务器。
- 服务器对账号和密码进行加密算法之后生成 session 文件,然后会在响应时将 set-cookie 带在响应头。
- 客户端接着会将 cookie 保存在内存中。
- 客户端下次请求的时候,会将 cookie 作为请求头发往服务器。
- 服务器将对客户端传过来的 cookie 与 session 文件进行校验,如果校验通过,则可以直接登录。
在购物场景中。
客户端会将用户已经选购的商品 1 发往服务器。
服务器会生成一份 session 文件,在响应时带上 set-cookie 发往客户端。
客户端会保存服务端传来的 cookie.
用户再次选择商品 2,进行以上同样的操作。
此时用户需要结账,客户端会将 cookie 发往服务器
进入结账页面时就会出现两个商品。
Cookie 缺点:
Cookie 的大小限制在 4kb 左右。对于复杂的存储来说是不够的
Cookie 会被附加在每个 HTTP 请求中,所以会增加 HTTP 请求大小
由于 Cookie 都是在 HTTP 请求中明文传递的,会有安全性问题(除非使用 HTTPS)
# cookie 属性
- name, value:是 Cookie 的名称和值
Cookie 的 name 和 value 必须经过 url 编码。在 JS 中可以通过 window.encodeURIComponent 方法来对 name 和 value 进行编码。同时,在写 cookie 的时候要注意,cookie 的名称是不区分大小写的。所以 myCookie 和 MyCookie 被认为是同一个 cookie。但是在实际开发过程中,最好区分大小写。
- domain:可以访问此 cookie 的域名
Cookie 对于哪个域是有效的。所以向该域发出的请求都会包含 Cookie 信息。设置 Cookie 时,如果不指定 Cookie 的值,默认就是本域名。如我在本地通过 Node.js 起服务器时,Cookie 的 domain 为 domain=localhost。
子域可以获取当前域(父域)的 cookie,但是当前域(父域)不能获取子域的 cookie。比如说,当前域为 a.com,在 a.com 设置了 cookie。那么其子域 b.a.com 可以获取 a.com 的 cookie。但是如果在 b.a.com 设置的 cookie,在 a.com 域名下不能获取到 b.a.com 下的 cookie。
- path:可以访问此 cookie 的页面路径
对于指定域中的那个路径,应该向服务器发送 cookie。默认情况下,如果不设置 Cookie 的 path 时,默认路径为/。比如说,在 a.com/profile 路径下设置的 cookie,那么在访问此路径的时候才会发送 cookie,在访问 a.com 时不会发送 cookie。
如果需要跨路径获取 Cookie 值,可以使用隐藏的 iframe 实现,但是必须是同源的。
- expires:cookie 超时时间
表示 Cookie 何时被删除的时间戳。这个时间戳是 GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT)。如果设置成以前的时间,则 Cookie 会被立即删除。如果设置的是将来的某个时间,那么即使关闭浏览器,cookie 仍然保持在用户的电脑上。expires 字段的设置与否,会把 Cookie 分为两种:本地(持久化)Cookie 和内存(非持久化)Cookie。在介绍分类的时候再细说。
- httpOnly:是否设置客户端脚本就无法通过 document.cookie 的方式读写 cookie
顾名思义,httpOnly 是指在 HTTP 层面上传输的 Cookie。当服务端对 Cookie 消息设置了 httpOnly 标志之后,客户端脚本就无法通过 document.cookie 的方式读写 cookie。能够读取意味着可以获取 Cookie,能够写入 Cookie 意味着可以篡改 Cookie。因此,对重要的 Cookie 消息设置 httpOnly 能够有效防御 XSS 攻击获取 Cookie。
- secure:设置是否只能通过 https 来传递此条 cookie
secure 表明设置了 secure 字段的 Cookie 只能在 HTTPS 上进行安全数据传输。如果请求是 HTTP 的,就不会带上这个 Cookie。这里要留心一点的是,服务端设置 cookie 下的 secure 字段,它并不是以名称-值对的形式的。而是单单一个 secure 单词。例如,Cookie 信息只能发送给https://keith.com,而http://keith.com的请求则不能发送Cookie。
如以下响应头,其他字段是名称-值对的形式,而secure是一个单词。
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: name=keith; domain=localhost; path=/; exipres=Mon, 08-June-18 07:10:24 GMT; secure
2
3
4
但是,有一个很特别的是设置了 secure 字段的 Cookie 可以被读写。因此,一般情况下,如果只允许 HTTPS 获取数据,服务端可以一起配置 secure + httpOnly 字段,这样就能够保证 HTTPS 传输,并且避免了 Cookie 被读写的风险。
- SameSite:
Chrome 51 开始,浏览器的 Cookie 新增加了一个 SameSite 属性,用来防止 CSRF 攻击和用户追踪。
值:
(1) Strict:完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
(2)Lax:Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
(3)None:Chrome 计划将 Lax 变为默认设置。这时,网站可以选择显式关闭 SameSite 属性,将其设为 None。不过,前提是必须同时设置 Secure 属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
参考:Cookie-阮一峰 (opens new window)
# session
# localstorage
HTML5 新方法,不过 IE8 及以上浏览器都兼容。
- 生命周期:持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
- 存储的信息在同一域中是共享的。
- 当本页操作(新增、修改、删除)了 localStorage 的时候,本页面不会触发 storage 事件,但是别的页面会触发 storage 事件。
- 大小:据说是 5M(跟浏览器厂商有关系)
- 在非 IE 下的浏览中可以本地打开。IE 浏览器要在服务器中打开。
- localStorage 本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
- localStorage 受同源策略的限制
操作
- 设置:
localStorage.setItem('username','cfangxu');
- 获取:
localStorage.getItem('username')
- 删除:
localStorage.removeItem('username')
- 情况:
localStorage.clear()
# sessionStorage
其实跟 localStorage 差不多,也是本地存储,会话本地存储
用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁,
sessionStorage 不是一种持久化的本地存储,仅仅是会话级别的存储,也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。关闭窗口后,sessionStorage 即被销毁,或者在新窗口打开同源的另一个页面,sessionStorage 也是没有的。
sessionStorage 在同一网站多个标签页内共享数据吗?这取决于标签页如何打开
通过点击链接(或者用了 window.open)打开的新标签页之间是属于同一个 session 的,但新开一个标签页总是会初始化一个新的 session,即使网站是一样的,它们也不属于同一个 session。
# web sql
# indexedDB
# UserData(IE 浏览器)
# 前端存储问题
# 1.cookie 和 session 区别
- 存储位置
cookie 数据保存在客户端,session 数据保存在服务器端。
- 安全性
cookie 对客户端是可见的,别有用心的人可以分析存放在本地的 cookie 并进行 cookie 欺骗,所以它是不安全的。
session 存储在服务器上,对客户端是透明的,不存在敏感信息泄漏的风险。
- 生命周期
cookie 的生命周期是累计时间,即如果我们 cookie 设置 setMaxAge(30),则 30 秒后失效
session 生命周期是间隔时间,如果设置 session 20min,只在 20min 内没有访问 session,则 session 失效
- 网络传输量
单个 cookie 保存的数据<=4K,session 没有上限
- 存储内容
cookie 只能保存字符串类型,以文本的方式。
session 通过类似与 Hashtable 的数据结构来保存,能支持任何类型的对象(session 中可含有多个对象)
# 2.localstorage 与 cookie 的区别
- 存储大小
cookie 数据大小不能超过 4k。
localStorage 和 sessionStorage 虽然也有存储大小的限制,但比 cookie 大得多,一般为 5M 左右。
- 有期时间
cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 的生命周期是仅在当前会话下有效。
sessionStorage 是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是 sessionStorage 在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage 也是不一样的。
- 存储位置
localStorage 和 sessionStorage 都保存在客户端,不与服务器进行交互通信
- 存储内容类型
cookie 只能保存字符串类型,以文本的方式。
localStorage 和 sessionStorage 只能存储字符串类型,对于复杂的对象可以使用 ECMAScript 提供的 JSON 对象的 stringify 和 parse 来处理
- 应用场景
localStorage:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据
sessionStorage:敏感账号一次性登录