前端storage使用分享

本文介绍了在前端开发中使用sessionStorage和localStorage时的安全策略与管理方案。包括数据封装、异常处理、数据加密、以及集中管理存储键,以确保用户数据安全并提高代码可维护性。同时提醒注意不要存储敏感数据,并限制存储量以防止超过存储上限。
摘要由CSDN通过智能技术生成

1. 背景

本文将介绍笔者在使用sessionStorage/localStorage时的方案,涉及数据管理、数据加密、API封装等内容,以供读者参考。

1.1 注意事项

  • 与用户相关的数据,如需存储,务必使用sessionStorage
  • 尽量不要存过多的数据在 storage 中,始终注意存储有上限。
  • 尽量避免使用 storage 存储敏感数据,尤其是localStorage

2. 方案

2.1 封装

由于 storage 对象在Safari无痕模式下是不可用状态,因此在使用 storage 时,需要做异常处理,因此推荐封装对 storage 的操作来统一处理兼容问题。示例代码请参见下文。

2.2 数据管理

如果不对 storage 做数据管理的话,很难从代码中全览项目中所存储的数据,因此推荐将数据的 key 做集中管理,以实现全览项目数据的目的。示例代码请参见下文。

2.3 数据安全(数据加密)

打开浏览器的开发者工具,便可直接查看当前存储在 storage 中的数据,如果有涉及相对敏感的数据,就有数据安全的问题,因此推荐使用加密存储的方式以减轻数据安全的问题。示例代码请参见下文。

3. 示例代码

3.1 封装&加密

笔者此处使用aes加密,数据加密只是为了做到相对安全,因此需考虑效率问题。

// index.js
export SessionStorageUtils from './session'
export LocalStorageUtils from './local'

// storage.js
import CryptoJS from 'crypto-js'

export const SECRET_PHRASE = 'secret_phrase'

export default class StorageUtils {
  static read (key, storage, encrypt = true) {
    try {
      let data = storage.getItem(key) || ''
      try {
        if (encrypt) {
          data = CryptoJS.AES.decrypt(data, SECRET_PHRASE).toString(
            CryptoJS.enc.Utf8
          )
        }
      } catch (e) {
        console.error(e.message)
      }
      return data
    } catch (e) {
      console.error(e.message)
    }

    return ''
  }

  static write (key, data, storage, encrypt = true) {
    try {
      if (encrypt) {
        data = CryptoJS.AES.encrypt(data, SECRET_PHRASE).toString()
      }

      return storage.setItem(key, data)
    } catch (e) {
      console.error(e.message)
    }
  }

  static readJSON (key, storage, encrypt = true) {
    try {
      const data = StorageUtils.read(key, storage, encrypt)
      if (data) {
        return JSON.parse(data)
      }
    } catch (e) {
      console.error(e.message)
    }

    return null
  }

  static writeJSON (key, data, storage, encrypt = true) {
    try {
      if (typeof data === 'object') {
        data = JSON.stringify(data)
      }
      StorageUtils.write(key, data, storage, encrypt)
    } catch (e) {
      console.error(e.message)
    }
  }

  static each (fn, storage, encrypt = true) {
    try {
      for (let i = storage.length - 1; i >= 0; i--) {
        const key = storage.key(i) || ''
        fn(StorageUtils.read(key, storage, encrypt), key)
      }
    } catch (e) {
      console.error(e.message)
    }
  }

  static remove (key, storage) {
    try {
      return storage.removeItem(key)
    } catch (e) {
      console.error(e.message)
    }
  }

  static clearAll (storage) {
    try {
      return storage.clear()
    } catch (e) {
      console.error(e.message)
    }
  }
}

// local.js
import StorageUtils from './storage'

export default class LocalStorageUtils {
  static read (key, encrypt = true) {
    return StorageUtils.read(key, localStorage, encrypt)
  }

  static readJSON (key, encrypt = true) {
    return StorageUtils.readJSON(key, localStorage, encrypt)
  }

  static write (key, data, encrypt = true) {
    return StorageUtils.write(key, data, localStorage, encrypt)
  }

  static writeJSON (key, data, encrypt = true) {
    return StorageUtils.writeJSON(key, data, localStorage, encrypt)
  }

  static each (fn, encrypt = true) {
    return StorageUtils.each(fn, localStorage, encrypt)
  }

  static remove (key) {
    return StorageUtils.remove(key, localStorage)
  }

  static clearAll () {
    return StorageUtils.clearAll(localStorage)
  }
}

// session.js
import StorageUtils from './storage'

export default class SessionStorageUtils {
  static read (key, encrypt = true) {
    return StorageUtils.read(key, sessionStorage, encrypt)
  }

  static readJSON (key, encrypt = true) {
    return StorageUtils.readJSON(key, sessionStorage, encrypt)
  }

  static write (key, data, encrypt = true) {
    return StorageUtils.write(key, data, sessionStorage, encrypt)
  }

  static writeJSON (key, data, encrypt = true) {
    return StorageUtils.writeJSON(key, data, sessionStorage, encrypt)
  }

  static each (fn, encrypt = true) {
    return StorageUtils.each(fn, sessionStorage, encrypt)
  }

  static remove (key) {
    return StorageUtils.remove(key, sessionStorage)
  }

  static clearAll () {
    return StorageUtils.clearAll(sessionStorage)
  }
}

3.2 数据管理

// src/storage-keys/local.js
export default class LocalKeys {
  static TEST_LOCAL = {
    KEY: 'test_local',
    DESCRIPTION: 'For test local',
  }
}

// src/storage-keys/session.js
export default class SessionKeys {
  static USER_INFO = {
    KEY: 'user_info',
    DESCRIPTION: 'This is current user data',
  }
}

// local.demo.js
import { LocalStorageUtils } from '@/utils/storage'
import LocalKeys from '@/storage-keys/local'

const test = LocalStorageUtils.read(SessionKeys.TEST_LOCAL.KEY)

// session.demo.js
import { SessionStorageUtils } from '@/utils/storage'
import SessionKeys from '@/storage-keys/session'

const userInfo = SessionStorageUtils.readJSON(SessionKeys.USER_INFO.KEY)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿祥_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值