这样讲 webStorage,面试官会对你刮目相看

图片:Unsplash

作者:Erda Estremera

localStorage 只在相同的域下共享同一空间。协议和端口都有影响,注意:

  • http://a.comhttps://a.com不共享

  • http://a.com:80http://a.com:8080 不共享

  • http://a.comhttp://a.com:80 共享

✔ 常用 API

设置 localStorage
Chrome 面板查看
  • localstorage.setItem(key, value) 存数据,key value 都会被转换成字符串,为了防止意料之外的情况,最好先将其转化为字符串了再存储;

  • localstorage.getItem(key) 获取数据,key 都会被转换成字符串;

  • localstorage.clear() 清除当前域下 localStorage 存储的数据;

  • localstorage.length 获取当前域下存储的项目条数;

  • localstorage.key(n:number) 获取显示面板中第 n 条的 key,感觉比较鸡肋;

✔ 浏览器对 localStorage 容量限制

经测试,Chrome、FireFox、Edge 都是 5M(IE 忽略)。

下面是容量探测代码,可以精确到 1K。

const add10KStr = new Array(1024).fill('0000000000').join('') // 10240 Byte => 10K
const add1KStr = new Array(1024).fill('1').join('') // 1024 Byte => 1K
const storageKey = 'QuotaTest'

function localStorageQuota() {
  localStorage.clear()
  function setText(str) {
    console.log(str)
  }
  let total = ''
  let interval = null
  interval = setInterval(() => {
    try {
      setText(`数据插入中 => ${total.length / 1024}K`)
      localStorage.removeItem(storageKey)
      localStorage.setItem(storageKey, total + add1KStr)
      total += add10KStr
    } catch (e) {
      clearInterval(interval)
      if (e && e.code === 22) {
        setText('超过容量(10K增加)')
        setText(`当前存储了${total.length / 1024}K`)
        interval = setInterval(() => {
          try {
            setText(`数据插入中 => ${total.length / 1024}K`)

            localStorage.removeItem(storageKey)
            localStorage.setItem(storageKey, total + add1KStr)
            total += add1KStr
          } catch (ee) {
            clearInterval(interval)
            if (ee && ee.code === 22) {
              setText('超过容量(1K增加)')
              setText(`当前存储了${total.length / 1024}K`)
            }
          }
        }, 0)
      }
    }
  }, 0)
}

以 Chrome 为 例,插入不了的时候会抛出异常,e.code 是 22。

localStorage error

✔ Storage Event

Storage 事件可以用来在同域下的页面之间实现广播机制,该事件是在 window 上触发的。该事件不在导致数据变化的当前页面(tab)触发(如果浏览器同时打开一个域名下面的多个页面,当其中的一个页面改变 localStorage 的数据时,其他所有页面的 storage 事件会被触发,而原始页面并不触发 storage 事件);

event 包含的关键信息:

  • event.key 发生变更的 key

  • event.oldValue 变更之前的值;

  • event.newValue 变更之后的值;

触发的条件有两个:

  1. 不在当前的 tab 触发,相同的 url 在两个不同的 tab 也是会触发的;

  2. localstorage.setItem(key, value) 只有当后一次设置的 value 不同的时候才会触发该事件,相同的话也没有必要触发了;

例如在 https://a.com/a.html 有如下代码:

localStorage.setItem('name', 'lx')
window.addEventListener('storage', e => {
  console.log('e', e)
})

这个时候,在 https://a.com/b.html 进行了下面的操作:

localStorage.setItem('name', 'lxfriday')

则 a 页面会打印出下面的内容:

storage event

✔ localStorage 的其他用途

ref

  • https://iammapping.com/the-other-ways-to-use-localstorage/

  1. 缓存静态文件;

  2. 作为前端 DB 的存储介质;

  • 灵活存取 json 格式的数据:https://github.com/typicode/lowdb

  • 通过 sql 对数据 CURD 操作:https://github.com/agershun/alasql#localstorage-and-dom-storage

✔ sessionStorage

它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除(关闭当前页面的时候会清除)

页面会话在浏览器打开期间一直保持,并且 重新加载(刷新) 或恢复页面仍会保持原来的页面会话。在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这句不好理解,意思是点击当前页面的 <a target="_black"></a> 标签时,在新页面中的 sessionStorage 的值是复制的当前页面的,注意并不是共用的。

✔ sessionStorage 应用

  1. 存储用户输入的内容,当页面刷新的时候可以立刻显示出刷新前的内容;

  2. 对使用 browser historay 部署的单页应用,可以在前端使用 sessionStorage 实现路由匹配(不会报 404),不需要使用 nginx 做一次转发;

实现自动匹配路由的过程是这样的:当访问 a.com/page1 页面的时候,由于服务器并没有这个页面,服务器会返回 404.html(浏览器当前的路由仍然是 a.com/page1),浏览器执行 404.html 时会先设置 sessionStorage.redirect 为当前的 url,然后 <meta> 会立刻让页面跳转到 /,服务器此时会返回 index.html,浏览器执行 <script> 中的代码获取到 sessionStorage.redirect,然后执行 histpry.replaceState 替换当前的 url,这样就达到了想要的跳转效果(history.replaceState 只会更改浏览器地址栏,不会让浏览器主动去服务器获取对应的页面)。

设置一个 404.htmlhead 中包含下面内容

<head>
    ...
    <script>
      sessionStorage.redirect = location.href;
    </script>
    <meta http-equiv="refresh" content="0;URL='/'"></meta>
</head>

在单页应用的模板 index.html 中,填下面的代码:

<body>
  <div id="root"></div>
  <script>
    // 这段代码要放在其他js的前面
    ;(function() {
      var redirect = sessionStorage.redirect
      delete sessionStorage.redirect
      if (redirect && redirect != location.href) {
        history.replaceState(null, null, redirect)
      }
    })()
  </script>
</body>

演示

sessionStorage 实现页面跳转

关注公众号,回复 加群 ,添加号主微信,将会拉你进交流群,有任何问题都会回复,欢迎加入。

感谢阅读,欢迎关注我的公众号 云影 sky,带你解读前端技术,掌握最本质的技能。

公众号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值