cookie
HTTP 协议是无状态的,HTTP 协议自身不对请求和响应之间的通信状态进行保存。
Cookie 指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。大小限制在 4KB 左右(cookie 每一个 name=value 的 value 值大概在 4KB)
Cookie 的本职工作并非本地存储,而是“维持状态”
应用场景
- 记住密码,下次自动登录
- 购物车功能
- 记录用户浏览数据,进行商品(广告)推荐
特点
cookie 是服务端生成,客户端进行维护和存储。
把 Cookie 理解为一个存储在浏览器里的一个小小的文本文件,它附着在 HTTP 请求上,在浏览器和服务器之间“飞来飞去”。
它可以携带用户信息,当服务器检查 Cookie 的时候,便可以获取到客户端的状态。
Cookie 是紧跟域名的。同一个域名下的所有请求,都会携带 同 domain 下的所有 Cookie。(对于静态文件的请求,携带 cookie 信息根本没有用,解决办法是:通过 cdn(存储静态文件的)的域名和主站的域名分开来解决。)
由于在 HTTP 请求中的 Cookie 是明文传递的,所以安全性成问题,除非用 HTTPS。关于 xss(Cross-site scripting) 攻击:
httpOnly
禁止 js 访问 cookie;Secure
标记意味着只在协议 https 的请求中携带;samesite
规定浏览器不能在跨域请求中携带 cookie,减少 csrf 攻击cookie 的新建和修改:
- xhr 请求的 response header 里的
set-cookie
如:set-cookie: MONITOR_WEB_ID=0fd86e6c-4e9f-427a-a76f-cf8593b98665; path=/; expires=Tue, 24 Aug 2021 06:14:03 GMT; domain=i.snssdk.com; samesite=none; secure
nodeJs 示例 - js
log(document.cookie);
或document.cookie = xxx
- request 的时候通过 request 的 cookie 向服务器传递所有 accessable 字段
- xhr 请求的 response header 里的
关键字 attribute
- Expires & Max-Age
- Secure & HttpOnly
- Domain & Path & SameSite & Cookie prefixes
踩坑:不设置domain,默认只操作当前hostname as domain,涉及修改domain=.xxx的情况需要注意
浏览器客户端每次发起请求 都会自动携带在 request-header 中
除了 cookie 外,本文其他所有存储方式都不会参与 服务端通信
本地存储 Web Storage
localStorage
- 特点
- 保存的数据长期存在,下一次访问该网站的时候,网页可以直接读取以前保存的数据。永远不会过期的,使其消失的唯一办法是手动删除
- 大小为 5M 左右
- 仅在客户端使用,不和服务端进行通信
- 接口封装较好,以
键值对
(只能存储字符串)的形式存在:存:localStorage.setItem("key","value");
取:var valueLocal = localStorage.getItem("key");
- the stored data is saved across browser sessions.
- 应用场景
考虑到 LocalStorage 的特点之一是持久,有时我们更倾向于用它来存储一些内容稳定的资源。比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串 - 作用域
localStorage 只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份 localStorage 数据。 - 使用
localStorage.setItem('myCat', 'Tom');
const cat = localStorage.getItem('myCat');
localStorage.removeItem('myCat');
localStorage.clear();
sessionStorage
- 特点
- 会话级别的浏览器存储:
- 保存的数据用于浏览器的一次会话,当会话结束(通常是该窗口关闭),数据被清空
- 即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 sessionStorage 内容便无法共享;localStorage 在所有同源窗口中都是共享的;cookie 也是在所有同源窗口中都是共享的。
- 大小为 5M 左右
- 仅在客户端使用,不和服务端进行通信
- 接口封装较好,属性和方法与 LocalStorage 完全一样。
- a unique page session gets created and assigned to that particular tab
- 使用场景
适合用来存储生命周期和它同步的会话级别的信息。这些信息只适用于当前会话,当你开启新的会话时,它也需要相应的更新或释放。
比如对表单信息进行维护,比如刷新时,表单信息不丢失。
比如微博的 sessionStorage 里有个 history 字段 里面是 json.stringify(pathArray) 就主要是存储你本次会话的浏览足迹 - 作用域
sessionStorage 比 localStorage 更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下 - 使用
CRUD 4 个操作同 localStorage
IndexedDB
https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory
是一种低级 API,用于客户端存储大量结构化数据(包括文件和 blobs)。
该 API 使用索引来实现对该数据的高性能搜索。
IndexedDB 是一个运行在浏览器上的非关系型 key-value 数据库。
理论上来说,IndexedDB 是没有存储上限的(一般来说不会小于 250M)。
它不仅可以存储字符串,还可以存储二进制数据。
特点
- 存储空间 一般不少于 250MB,甚至没有上限
- key-value 存储: 所有类型可以直接存入。包括 object, 甚至二进制文件 Buffer
ArrayBuffer
对象和Blob
对象,见MDN。相比localStorage
直接以对象的形式存入,无需转为 JSON 字符串 - 异步 get & set。因为目标场景就是大量数据的 CURD。当存储一个较大数据时,不会因为写入数据慢 导致页面阻塞
- 同源限制:一个数据库 correspond 创建它的域名。浏览器 tab 只能访问自身域名下的数据库(们)。IndexedDB 和 localStorage 一样,都是有同源策略的问题,不能跨协议、端口、域名使用。
- 支持事务。意味着 一系列操作步骤中,只要有一部失败,整个事务都会取消,数据库回滚到事务发生之前的状态,不存在只改写一部分的情况.能确保我们多个操作只要其中一步出现问题,可以整体回滚。
操作方法
不是常用的调用方法 -> 返回结果的模式。而是请求 -> 响应- 建立打开 IndexedDB
window.indexedDB.open("testDB")
返回一个IDBRequest 对象IDBRequest
对象(inherits from from EventTarget.) 包括几个属性 properties:
都是 read only.error
.result
: Returns the result of the request. 通常是个IDBDatabase 对象 If the request failed and the result is not available, an InvalidStateError exception is thrown.source
: Return the source of the request.比如一个 IDBIndex 或 IDBObjectStore. 没有的话就 null.readyState
: Return the state of the request. 所有 IDBRequest 对象的 state 只有一种变化pending -> done
。whenever the request completes successfully or when an error occurs.transaction
: 此次 request 处理的事务。(某些情况下是 null,比如indexedDB.open
就只是 connecting to a database, so there is no transaction to return)
同时继承了EventTarget
的三个方法:addEventListener
,removeEventListener
&dispatchEvent
两个事件 events.onerror
: 请求失败的回调.onsuccess
: 请求成功的回调.onupgradeneeded
: 请求数据库版本变化的回调
- 关闭 IndexedDB
indexdb.close()
- 删除 IndexedDB
window.indexedDB.deleteDatabase(indexdb)
- 建立打开 IndexedDB
应用场景
缓存大数据,将数据缓存到本地,下次打开列表后,发现如果 url 中的 id 和缓存的数据 id 一致,那么就直接使用缓存数据,不再进行请求;
例子:
function openDB(name) {
var request = window.indexedDB.open(name); //建立打开IndexedDB
request.onerror = function (e) {
console.log("open indexdb error");
};
request.onsuccess = function (e) {
myDB.db = e.target.result; //这是一个 IDBDatabase对象,这就是IndexedDB对象
console.log(myDB.db); //此处就可以获取到db实例
};
}
var myDB = {
name: "testDB",
version: "1",
db: null,
};
openDB(myDB.name);