Session(存在服务端)Session实际上就是普通的数据而已,存在数据库或者Redis中特殊的在于一般Session有特殊的维护Session机制:在数据库/Redis中建一张Session表,包括SessionId,用户Id,过期时间用Cookie携带SessionId,过期时间往往是当前时间Cookie要保存的时间每次传回来Cookie检查SessionId对应的时间是否已经过期,过期了则要求重新登录,否则用对应的用户Id获取需要的数据数据清理方式有两种: 每次请求的时候检查是否过期,若过期就清理掉,这种方式简单但会让过期的Id有时候会长时间留在数据库中,因为一直没请求 / 定时检查整个表,清理掉过期的数据Cookie(存在客户端)Cookie相当于一串标识符,存在浏览器本地目录的一个目录下,第一次登录网站生成这个cookie,存入这个目录,之后当进入这个网站的时候会自动去这个网站对应的cookie文件夹拿cookie,然后用cookie从数据库找到登录信息自动登录,注意cookie和密码区别在于持久性不同,cookie可以由服务器控制权限时间,并且用户也可以注销登录等方式控制,一般4KB,每个域名下约20-50个,明文传输主要属性:NameValue : 键值对,存储实际数据,一般存的是用户的身份标识,像sessionId或token(不要存密码!),value往往需要URL编码(即将非ASCII码字符编码为%加数字的形式)Domin: 指定哪些主机可以接收该Cookie,不手动设置的话默认当前域名(注意当前域名指的是请求的这个域名,不包含子域名,比如说发过来的请求是http://abc.example.com/nt,那么不手动设置的话是.example.com,他会匹配所有的比如sn.example.com,lao.example.com)Path : 在指定URL路径下才发送Cookie,默认是当前url目录部分,即http://abc.example.com/nt会取/,然后http://abc.example.com/nt/yes会取/ntExpires: 设置Cookie过期时间Max-Age: 设置Cookie有效秒数,优先级高于ExpiresSecure: 设置该Cookie只能通过HTTPS协议传输HttpOnly: 禁止JS通过document.cookie访问Cookie,可以防御XSSSameSite: 控制跨站是否携带,None(跨站都携带)/Lax(除了点击跳转链接和get请求都不携带)/Strict(跨站都不携带)Cookie的制作与使用:服务器通过HTTP响应头的Set-Cookie来设置Cookie属性浏览器根据属性保存并遵循同源策略(DominPath)浏览器根据SameSite的设置携带Cookie常见攻击方式:CSRFXSS: 往同源页面注入document.cookie窃取cookie防御:设置HttpOnly中间人攻击: 用户连接到一个伪造的WIFI热点,攻击者在热点上设置代理拦截所有经过的流量,中间就包括Cookie防御: 使用HTTPS代替HTTP这样拿到信息也无法解密Cookie,另外设置Web Storage(存在客户端)分类:SessionStorage: 只存在于当前标签页,当前标签页一旦关闭就销毁,无法跨标签页使用,一般5-10MBLocalStorage: 长期保存,只要不手动销毁就一直保存,哪怕浏览器关了他也在,一般5-10MB缺点:只能存字符串操作是同步的,大量数据的查询回导致页面卡断只能通过key查询获取值IndexDB(存在客户端)浏览器原生的NoSQL数据库系统,但是底层api太复杂一般最好封装优势:跟localStorage很相似,但是存储量大得多可以存各种类型的数据异步非阻塞,通过事件或Promise返回结果支持ACID事务,支持回滚可以创建索引加速查询受同源策略保护,一个源的网页无法访问其他源的数据典型用途:页面,样式,脚本,用户数据等缓存频繁请求的api数据(比如商品目录等)浏览器清理:浏览器通常用可用硬盘50%的空间作为空间大小达到限制后用LRU算法清理自动清理修改:请求持久存储: 可以用api向浏览器请求持久存储,大大降低被清理风险(不能完全消除)监控存储状态来防止超限设计被清除之后重新从服务器获取设置功能给用户开放清除数据的权限操作:数据库声明周期: open()打开或创建一个新数据库 / deleteDatabase()删除数据库对象存储管理: createObjectStore()创建一个对象仓库 / deleteObjectStore()删除一个对象仓库 / createIndex()为对象仓库创建索引 / deleteIndex()删除索引数据操作: add()向仓库添加数据 / put()更新或添加数据,若主键已存在则更新 / get()通过主键获取一条数据 / delete()通过主机爱你删除一条数据 / clear()清空整个仓库的所有数据数据查询: getAll()获取仓库中的所有数据或满足某个索引条件的所有数据 / openCursor()打开一个游标,用于遍历,过滤或批量处理数据 / count()计算仓库或索引中的数据条数事务管理: transaction()创建事务,所有数据读写必须在事务中完成 / abort()终止当前事务,回滚所有更改用法:// 打开名为 MyTestDatabase 的数据库版本号为 3,注意这个版本号在增删改的时候需要改为更高的,通过版本号更高来告诉浏览器数据被更新了constrequestwindow.indexedDB.open(MyTestDatabase,3);request.onupgradeneeded(event){constdbevent.target.result;// 检查并创建一个名为 customers 的对象仓库(相当于数据库的表)主键为 idif(!db.objectStoreNames.contains(customers)){constobjectStoredb.createObjectStore(customers,{keyPath:id});// 为 name 字段创建索引方便后续快速查询objectStore.createIndex(name,name,{unique:false});}};