当前位置:网站首页>Some high-level usage of localstorage
Some high-level usage of localstorage
2022-06-29 06:37:00 【Front end talent】

A lot of people are using it localStorage or sessionStorage I like to use it directly , Plaintext storage , Expose information directly to ; Browser , Although it can be handled in ordinary scenes and is simple and rough , But in case of special needs , For example, set the timing function , Can't achieve . It needs to be re encapsulated , In order to increase the sense of security in use , Encryption must be indispensable . For the convenience of the project , It is specially used to encapsulate routine operation . The imperfections will be further updated ...( Updated on :2022.06.02 16:30)
Design
Sort out the required functions before packaging , And what to make , What kind of specifications are used , Some of the main code snippets are based on localStorage As an example , Finally, the complete code will be posted . It can be optimized by itself in combination with the project , It can also be used directly .
// Differentiate storage types type
// Custom name prefix prefix
// Support setting expiration time expire
// Support encryption optional , Encryption can be turned off if debugging is not convenient in the development environment
// Support data encryption Here the crypto-js encryption Other methods can also be used
// Judge whether to support Storage isSupportStorage
// Set up setStorage
// obtain getStorage
// Whether there is hasStorage
// Get all key getStorageKeys
// Get... According to the index key getStorageForIndex
// obtain localStorage length getStorageLength
// Access to all getAllStorage
// Delete removeStorage
// Empty clearStorage
// Defining parameters type window.localStorage,window.sessionStorage,
const config = {
type: 'localStorage', // Local storage type localStorage/sessionStorage
prefix: 'SDF_0.0.1', // Name prefix Suggest : Project name + Project version
expire: 1, // Expiration time Company : second
isEncrypt: true // Default encryption For debugging convenience , The development process can not be encrypted
}
Copy code Set up setStorage
Storage The expiration time setting is not supported , To support setting expiration time , You can follow the example of Cookie How to do it ,setStorage(key,value,expire) Method , Receive three parameters , The third parameter is to set the expiration time , In relative time , Unit second , Type check the passed parameters . You can set a uniform expiration time , The expiration time of a single value can also be configured separately . Two methods of on-demand configuration .
Code implementation :
// Set up setStorage
export const setStorage = (key,value,expire=0) => {
if (value === '' || value === null || value === undefined) {
value = null;
}
if (isNaN(expire) || expire < 1) throw new Error("Expire must be a number");
expire = (expire?expire:config.expire) * 60000;
let data = {
value: value, // Stored value
time: Date.now(), // Save value timestamp
expire: expire // Expiration time
}
window[config.type].setItem(key, JSON.stringify(data));
}
Copy code obtain getStorage
First of all, we have to deal with key Whether there is a judgment , To prevent an error from getting a nonexistent value . Further extension of the acquisition method , As long as it is obtained within the validity period Storage value , Just renew the expiration date , If it expires, the value will be deleted directly . And back to null
// obtain getStorage
export const getStorage = (key) => {
// key There is no judgment
if (!window[config.type].getItem(key) || JSON.stringify(window[config.type].getItem(key)) === 'null'){
return null;
}
// Optimize Renewal in continuous use
const storage = JSON.parse(window[config.type].getItem(key));
console.log(storage)
let nowTime = Date.now();
console.log(config.expire*6000 ,(nowTime - storage.time))
// Expired delete
if (storage.expire && config.expire*6000 < (nowTime - storage.time)) {
removeStorage(key);
return null;
} else {
// Called before expiration Automatically renew Keep alive
setStorage(key,storage.value);
return storage.value;
}
}
Copy code Get all values
// Access to all getAllStorage
export const getAllStorage = () => {
let len = window[config.type].length // To obtain the length of the
let arr = new Array() // Define datasets
for (let i = 0; i < len; i++) {
// obtain key Index from 0 Start
let getKey = window[config.type].key(i)
// obtain key Corresponding value
let getVal = window[config.type].getItem(getKey)
// Put it in the array
arr[i] = { 'key': getKey, 'val': getVal, }
}
return arr
}
Copy code Delete removeStorage
// Prefix the name automatically
const autoAddPrefix = (key) => {
const prefix = config.prefix ? config.prefix + '_' : '';
return prefix + key;
}
// Delete removeStorage
export const removeStorage = (key) => {
window[config.type].removeItem(autoAddPrefix(key));
}
Copy code Empty clearStorage
// Empty clearStorage
export const clearStorage = () => {
window[config.type].clear();
}
Copy code encryption 、 Decrypt
Encryption uses crypto-js
// install crypto-js
npm install crypto-js
// introduce crypto-js There are two ways
import CryptoJS from "crypto-js";
// perhaps
const CryptoJS = require("crypto-js");
Copy code Yes crypto-js Set the key and key offset , A private key can be passed through MD5 Encryption generation 16 Bit key acquisition .
// A hexadecimal number as a key
const SECRET_KEY = CryptoJS.enc.Utf8.parse("3333e6e143439161");
// Hexadecimal number as key offset
const SECRET_IV = CryptoJS.enc.Utf8.parse("e3bbe7e3ba84431a");
Copy code Encapsulate the encryption method
/**
* Encryption method
* @param data
* @returns {string}
*/
export function encrypt(data) {
if (typeof data === "object") {
try {
data = JSON.stringify(data);
} catch (error) {
console.log("encrypt error:", error);
}
}
const dataHex = CryptoJS.enc.Utf8.parse(data);
const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}
Copy code Encapsulate the decryption method
/**
* Decryption method
* @param data
* @returns {string}
*/
export function decrypt(data) {
const encryptedHexStr = CryptoJS.enc.Hex.parse(data);
const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
Copy code It is used in storing data and acquiring data :
Here we mainly look at the encryption and decryption part , Some methods are not shown in the following code snippet , Please note that , Can't run directly .
const config = {
type: 'localStorage', // Local storage type sessionStorage
prefix: 'SDF_0.0.1', // Name prefix Suggest : Project name + Project version
expire: 1, // Expiration time Company : second
isEncrypt: true // Default encryption For debugging convenience , The development process can not be encrypted
}
// Set up setStorage
export const setStorage = (key, value, expire = 0) => {
if (value === '' || value === null || value === undefined) {
value = null;
}
if (isNaN(expire) || expire < 0) throw new Error("Expire must be a number");
expire = (expire ? expire : config.expire) * 1000;
let data = {
value: value, // Stored value
time: Date.now(), // Save value timestamp
expire: expire // Expiration time
}
// Encrypt the stored data Encryption is optional
const encryptString = config.isEncrypt ? encrypt(JSON.stringify(data)): JSON.stringify(data);
window[config.type].setItem(autoAddPrefix(key), encryptString);
}
// obtain getStorage
export const getStorage = (key) => {
key = autoAddPrefix(key);
// key There is no judgment
if (!window[config.type].getItem(key) || JSON.stringify(window[config.type].getItem(key)) === 'null') {
return null;
}
// Decrypt the stored data
const storage = config.isEncrypt ? JSON.parse(decrypt(window[config.type].getItem(key))) : JSON.parse(window[config.type].getItem(key));
let nowTime = Date.now();
// Expired delete
if (storage.expire && config.expire * 6000 < (nowTime - storage.time)) {
removeStorage(key);
return null;
} else {
// It will be automatically renewed when it is used continuously
setStorage(autoRemovePrefix(key), storage.value);
return storage.value;
}
}
Copy code Use
You can use it by import Introduce on demand , You can also mount it to the global server , It is generally recommended to use less global methods or global variables , For those who continue to develop and maintain the project later , Trace the code and leave a convenient way ! Don't encapsulate for encapsulation , As far as possible, it is based on the project requirements and subsequent common , And the convenience of use . For example, get all storage variables , If you haven't used it on your project , It would be better to delete , It doesn't have much fragrance to keep for the new year , It's better to make some contribution to reducing the volume !
import {isSupportStorage, hasStorage, setStorage,getStorage,getStorageKeys,getStorageForIndex,getStorageLength,removeStorage,getStorageAll,clearStorage} from '@/utils/storage'
Copy code Complete code
The code has been further improved , What you need can be further optimized directly , You can also optimize or extend the recommendations , Message description , I will iterate further . You can delete some unused methods according to your own needs , To reduce file size .
/***
* title: storage.js
* Author: Gaby
* Email: [email protected]
* Time: 2022/6/1 17:30
* last: 2022/6/2 17:30
* Desc: Simple encapsulation of storage
*/
import CryptoJS from 'crypto-js';
// A hexadecimal number as a key
const SECRET_KEY = CryptoJS.enc.Utf8.parse("3333e6e143439161");
// Hexadecimal number as key offset
const SECRET_IV = CryptoJS.enc.Utf8.parse("e3bbe7e3ba84431a");
// type window.localStorage,window.sessionStorage,
const config = {
type: 'localStorage', // Local storage type sessionStorage
prefix: 'SDF_0.0.1', // Name prefix Suggest : Project name + Project version
expire: 1, // Expiration time Company : second
isEncrypt: true // Default encryption For debugging convenience , The development process can not be encrypted
}
// Judge whether to support Storage
export const isSupportStorage = () => {
return (typeof (Storage) !== "undefined") ? true : false
}
// Set up setStorage
export const setStorage = (key, value, expire = 0) => {
if (value === '' || value === null || value === undefined) {
value = null;
}
if (isNaN(expire) || expire < 0) throw new Error("Expire must be a number");
expire = (expire ? expire : config.expire) * 1000;
let data = {
value: value, // Stored value
time: Date.now(), // Save value timestamp
expire: expire // Expiration time
}
const encryptString = config.isEncrypt
? encrypt(JSON.stringify(data))
: JSON.stringify(data);
window[config.type].setItem(autoAddPrefix(key), encryptString);
}
// obtain getStorage
export const getStorage = (key) => {
key = autoAddPrefix(key);
// key There is no judgment
if (!window[config.type].getItem(key) || JSON.stringify(window[config.type].getItem(key)) === 'null') {
return null;
}
// Optimize Renewal in continuous use
const storage = config.isEncrypt
? JSON.parse(decrypt(window[config.type].getItem(key)))
: JSON.parse(window[config.type].getItem(key));
let nowTime = Date.now();
// Expired delete
if (storage.expire && config.expire * 6000 < (nowTime - storage.time)) {
removeStorage(key);
return null;
} else {
// Called before expiration Automatically renew Keep alive
setStorage(autoRemovePrefix(key), storage.value);
return storage.value;
}
}
// Whether there is hasStorage
export const hasStorage = (key) => {
key = autoAddPrefix(key);
let arr = getStorageAll().filter((item)=>{
return item.key === key;
})
return arr.length ? true : false;
}
// Get all key
export const getStorageKeys = () => {
let items = getStorageAll()
let keys = []
for (let index = 0; index < items.length; index++) {
keys.push(items[index].key)
}
return keys
}
// Get... According to the index key
export const getStorageForIndex = (index) => {
return window[config.type].key(index)
}
// obtain localStorage length
export const getStorageLength = () => {
return window[config.type].length
}
// Access to all getAllStorage
export const getStorageAll = () => {
let len = window[config.type].length // To obtain the length of the
let arr = new Array() // Define datasets
for (let i = 0; i < len; i++) {
// obtain key Index from 0 Start
let getKey = window[config.type].key(i)
// obtain key Corresponding value
let getVal = window[config.type].getItem(getKey)
// Put it in the array
arr[i] = {'key': getKey, 'val': getVal,}
}
return arr
}
// Delete removeStorage
export const removeStorage = (key) => {
window[config.type].removeItem(autoAddPrefix(key));
}
// Empty clearStorage
export const clearStorage = () => {
window[config.type].clear();
}
// Prefix the name automatically
const autoAddPrefix = (key) => {
const prefix = config.prefix ? config.prefix + '_' : '';
return prefix + key;
}
// Remove the added prefix
const autoRemovePrefix = (key) => {
const len = config.prefix ? config.prefix.length+1 : '';
return key.substr(len)
// const prefix = config.prefix ? config.prefix + '_' : '';
// return prefix + key;
}
/**
* Encryption method
* @param data
* @returns {string}
*/
const encrypt = (data) => {
if (typeof data === "object") {
try {
data = JSON.stringify(data);
} catch (error) {
console.log("encrypt error:", error);
}
}
const dataHex = CryptoJS.enc.Utf8.parse(data);
const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}
/**
* Decryption method
* @param data
* @returns {string}
*/
const decrypt = (data) => {
const encryptedHexStr = CryptoJS.enc.Hex.parse(data);
const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
Copy code About this article
come from :Gaby
https://juejin.cn/post/7104301566857445412
Last
边栏推荐
- Unity AR Shadow 阴影
- [deep learning] - maze task learning I (to realize the random movement of agents)
- WDCP访问不存在的路径全部跳转到首页不返回404的解决办法
- National Defense University project summary
- Meta metauniverse female safety problems occur frequently. How to solve the relevant problems in the metauniverse?
- After “Go to Definition”, is there a command to return to where you came from?
- How to use regex in file find
- Rearrangement string of leetcode simple question
- Longest substring between two identical characters of leetcode simple question
- Venn diagram proportional and color shading with semi transparency
猜你喜欢

二叉树的迭代法前序遍历的两种方法

VLAN experiment

Fault: KDC warning log for id29

Segment in Lucene

Part 63 - interpreter and compiler adaptation (II)

Test Development - ten years of sharpening one sword (VII) interface test tool postman

The most complete machine learning model training process

配置Flutter开发环境

Are there too many programmers in China at present?

Jenkins operation Chapter 5 trigger, configuration webhook, Jenkins parameterized construction
随机推荐
SCM engineering experience - time slice
Creation of Arduino uno development environment
Illustrate plug-in -- AI plug-in development -- creative plug-in -- astute graphics -- multi axis mirroring function
Are there too many programmers in China at present?
Teach you how to develop your own NPM package (publish to the NPM official website)
Principle of screen printing adjustment of EDA (cadence and AD) software
[Flink] flinksql and table programming cases
配置Flutter开发环境
[deep learning] - maze task learning I (to realize the random movement of agents)
Can I cast int to a variable of type byte? What happens if the value is larger than the range of byte type?
Difference between URI and URL
Games101 Lecture 10 geometry 1 Notes
Fault: ntfrs warning log for id13562
Hustoj SPJ example
Monitor employee turnover dynamics. This system makes employees tremble!
Can redis implement hot standby?
Client and server working modes of JVM
AIRNET notes 1
2022.02.15 - SX10-31. House raiding III
[MySQL technology topic] technical analysis and guide for analyzing the high availability architecture of MySQL