• 浏览器缓存总结(cookie、localStorage、sessionStorage)


    Cookie

    简介

    Cookie 的本职工作并非本地存储,而是“维持状态”。因为HTTP协议是无状态的,HTTP协议自身不对请求和响应之间的通信状态进行保存,,通俗来说,服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,于是就诞生了Cookie。它就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。
    
    我们可以把Cookie 理解为一个存储在浏览器里的一个小小的文本文件,它附着在 HTTP 请求上,在浏览器和服务器之间“飞来飞去”。它可以携带用户信息,当服务器检查 Cookie 的时候,便可以获取到客户端的状态。
    
    在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把Cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。结帐时,服务器读取发送来的Cookie就行了。
    

    使用场景

    • 记住密码,下次自动登录
    • 购物车功能
    • 记录用户浏览数据,进行商品(广告)推荐

    原理

    第一次访问网站的时候,浏览器发出请求,服务器响应请求后,会在响应头里面添加一个Set-Cookie选项,将cookie放入到响应请求中,在浏览器第二次发请求的时候,会通过Cookie请求头部将Cookie信息发送给服务器,服务端会辨别用户身份,另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定
    

    读写操作

    • 操作浏览器对象

      //设置
      	//设置cookie
      	document.cookie = "userId=nick123" 
      	//设置过期时间
      	document.cookie = "userId=nick123; expires=Wed, 15 Jan 2020 12:00:00 UTC"
          //设置所属路径,默认当前页面路径
      	document.cookie = "userId=nick123; expires=Wed, 15 Jan 2020 12:00:00 UTC; path=/user" 
      	//设置cookie域
      document.cookie = "userId=nick123; expires=Wed, 15 Jan 2020 12:00:00 UTC; path=/user; domain=mysite.com" 
      
      //读取
      	//获取所有cookie
      	const cookies = document.cookie 
      	//使用正则读取指定名称的cookie
          function getCookieValue(name) {
            let result = document.cookie.match("(^|[^;]+)\s*" + name + "\s*=\s*([^;]+)")
            return result ? result.pop() : ""
          } 
      	//不使用正则读取指定cookie
          function getCookieValue(name) {
            const nameString = name + "="
            const value = document.cookie.split(";").filter(item => {
              return item.includes(nameString)
            })
            if (value.length) {
              return value[0].substring(nameString.length, value[0].length)
            } else {
              return ""
            }
          }
      //修改
      	//已覆盖的方式修改
      	document.cookie = "userId=new_value"
      //删除
      	document.cookie = "userId=; expires=Thu, 01 Jan 1970 00:00:00 UTC;"
      
    • 使用npm库

      npm i js-cookie -S
      
      import Cookies from 'js-cookie'
      //设置cookie
      Cookies.set('foo', 'bar')
      //设置过期时间
      Cookies.set('name', 'value', { expires: 7 })
      //设置所属路径
      Cookies.set('name', 'value', { expires: 7, path: '' })
      //读取
      Cookies.get('name') 
      //读取所有
      Cookies.get()
      //读取所属域下的cookie
      Cookies.get('foo', { domain: 'sub.example.com' }) 
      //删除
      Cookies.remove('name')
      

    Cookie的缺陷

    • Cookie 不够大

      Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的。当 Cookie 超过 4KB 时,它将面临被裁切的命运。这样看来,Cookie 只能用来存取少量的信息。此外很多浏览器对一个站点的cookie个数也是有限制的。
      
      这里需注意:各浏览器的cookie每一个name=value的value值大概在4k,所以4k并不是一个域名下所有的cookie共享的,而是一个name的大小
      
    • 过多的 Cookie 会带来巨大的性能浪费

      Cookie 是紧跟域名的。同一个域名下的所有请求,都会携带 Cookie。大家试想,如果我们此刻仅仅是请求一张图片或者一个 CSS 文件,我们也要携带一个 Cookie 跑来跑去(关键是 Cookie 里存储的信息并不需要),这是一件多么劳民伤财的事情。Cookie 虽然小,请求却可以有很多,随着请求的叠加,这样的不必要的 Cookie 带来的开销将是无法想象的。
      
      cookie是用来维护用户信息的,而域名(domain)下所有请求都会携带cookie,但对于静态文件的请求,携带cookie信息根本没有用,此时可以通过cdn(存储静态文件的)的域名和主站的域名分开来解决
      
    • 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用HTTPS

    Cookie与安全

    属性 作用
    value 如果用于保存用户登录状态,应该要将该字段加密,不能使用明文的用户标识
    http-only 不能通过js访问Cookie,减少XSS攻击
    secure 只能在协议为https的请求中携带
    same-site 规定浏览器不能在跨域请求中携带Cookie,减少CSRF攻击

    LocalStorage

    特点

    • 保存的数据长期存在(直到清除浏览器的缓存),下一次访问该网站的时候,网页可以直接读取以前保存的数据
    • 大小为5M左右
    • 仅在客户端使用,不和服务端进行通信
    • 接口封装较好

    使用场景

    LocalStorage可以作为浏览器本地缓存方案,用来提升网页首屏渲染速度(根据第一请求返回时,将一些不变信息直接存储在本地)

    读写操作

    localStorage.setItem(key,value)  保存数据
    localStorage.getItem(key)        获取数据
    localStorage.removeItem(key)     删除数据
    localStorage.clear();            删除全部数据
    

    sessionStorage

    简介

    sessionStorage保存的数据用于浏览器的一次会话,当会话结束(通常是该窗口关闭),数据被清空;sessionStorage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 sessionStorage 内容便无法共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。除了保存期限的长短不同,SessionStorage的属性和方法与LocalStorage完全一样
    

    特点

    • 会话级别的浏览器存储
    • 大小为5M左右
    • 仅在客户端使用,不和服务端进行通信
    • 接口封装较好

    使用场景

    有效对表单信息进行维护,比如刷新时,表单信息不丢失

    读写操作

    sessionStorage.setItem(key,value)  保存数据
    sessionStorage.getItem(key)        获取数据
    sessionStorage.removeItem(key)     删除数据
    sessionStorage.clear();            删除全部数据
    
    • 共同点
    • 都是保存在浏览器端,且都遵循同源策略
    • 只能存储字符串
    • 不同点
    • 生命周期

      • localStorage 是持久化的本地存储,存储在其中的数据是永远不会过期的,使其消失的唯一办法是手动删除
      • sessionStorage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放
    • 作用域

      • localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据
      • sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(当前同一个源下面的只要有一个窗口没关或者跳到另外的窗口,sessionStorage都会存在)下

    Web Storage 是一个从定义到使用都非常简单的东西,它使用键值对的形式进行存储,这种模式有点类似于对象,却甚至连对象都不是——它只能存储字符串,要想得到对象,我们还需要先对字符串进行一轮解析。Web Storage 是对 Cookie 的拓展,它只能用于存储少量的简单数据。当遇到大规模的、结构复杂的数据时,Web Storage 也爱莫能助了。这时候我们就要清楚我们的终极大 boss——IndexedDB

    IndexedDB

    简介

    indexedDB是一个运行在浏览器上的非关系型数据库,没有存储上线,一般不会小于250M,它不仅可以储存字符串,还可以储存二进制数据。

    IndexedDB的特点

    • 键值对存储
    IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误
    
    • 异步
    IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现
    
    • 支持事务
    IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
    
    • 同源限制
    IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库
    
    • 储存空间大
    IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限
    
    • 支持二进制储存
    IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)
    

    IndexedDB的常见操作

    • 建立打开IndexedDB ----window.indexedDB.open("testDB")
    function openDB(name) {
    	var request = window.indexedDB.open(name) //建立打开IndexedDB
    	console.log('request', request)
    	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)
    
    • 关闭IndexedDB----indexdb.close()
    function closeDB(db){
        db.close();
    }
    
    • 删除IndexedDB----window.indexedDB.deleteDatabase(indexdb)
    function deleteDB(name) {
      indexedDB.deleteDatabase(name)
    }
    

    总结

    • Cookie 的本职工作并非本地存储,而是“维持状态”
    • Web Storage 是 HTML5 专门为浏览器存储而提供的数据存储机制,不与服务端发生通信
    • IndexedDB 用于客户端存储大量结构化数据

    参考

    https://www.jianshu.com/p/8e86bf912b0e

    https://juejin.im/post/5d8c33cb5188255a12365056

    https://github.com/js-cookie/js-cookie

    https://github.com/ljianshu/Blog/issues/25

  • 相关阅读:
    微信h5下拉隐藏网页,还有取消页面滑动
    vuejs中使用递归嵌套组件
    运行gitbook init命令报错及问题解决办法
    利用python生成gitbook目录文件
    通过Appium日志,分析其运行原理
    字符串两两更换位置
    Dockerfile启动的程序,内存不断增长问题
    测试流程优化
    APP测试面试题(一)
    关于面试总结13-app测试面试题
  • 原文地址:https://www.cnblogs.com/TomAndJerry/p/12703329.html
Copyright © 2020-2023  润新知