成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文讀懂瀏覽器本地存儲:Web Storage

存儲 存儲架構
在我們的一些內部系統中,用戶信息是每個頁面都要用到的,尤其是 userId 字段,會與每個獲取數據接口掛鉤,但這個數據是不會變的,一直請求是沒有意義的,為減少接口的訪問次數,可以將主要數據緩存在 localStorage 內,方便其他接口獲取。

一、 簡介

瀏覽器本地存儲是指瀏覽器提供的一種機制,允許 Web 應用程序在瀏覽器端存儲數據,以便在用戶下次訪問時可以快速獲取和使用這些數據。一共兩種存儲方式:localStorage 和 sessionStorage。下面介紹下兩種緩存的特性和在內部平臺的一些應用。

二、localStorage 和 sessionStorage

2.1、區別

localStorage 和 sessionStorage 的主要區別是生命周期,具體區別如下:


localStorage

sessionStorage

生命周期

持久化存儲:除非自行刪除或清除緩存,否則一直存在

會話級別的存儲:瀏覽器標簽頁或窗口關閉

作用域

相同瀏覽器,同域名,不同標簽,不同窗口

相同瀏覽器,同域名,同源窗口

獲取方式

window.localStorage

window.sessionStorage

存儲容量

5M

5M

容量限制的目的是防止濫用本地存儲空間,導致用戶瀏覽器變慢。

2.2、瀏覽器兼容性

1)現在的瀏覽器基本上都是支持這兩種 Storage 特性的。各瀏覽器支持版本如下:


Chrome

Firefox

IE

Opera

Safari

Android

Opera Mobile

Safari Mobile

localStorage

4

3.5

8

10.5

4

2.1

11

iOS 3.2

sessionStorage

5

2

8

10.5

4

2.1

11

iOS 3.2

2)如果使用的是老式瀏覽器,比如Internet Explorer 6、7 或者其他,就需要在使用前檢測瀏覽器是否支持本地存儲或者是否被禁用。以 localStorage 為例:

if(window.localStorage){
  alert("瀏覽器支持 localStorage");
} else {
  alert("瀏覽器不支持 localStorage");
}

3)某些瀏覽器版本使用過程中,會出現 Storage 不能正常使用的情況,記得添加 try/catch。以 localStorage 為例:

if(window.localStorage){
  try {
    localStorage.setItem("username", "name");
    alert("瀏覽器支持 localStorage");
  } catch (e) {
    alert("瀏覽器支持 localStorage 后不可使用");
  }
} else {
  alert("瀏覽器不支持 localStorage");
}

三、使用說明

3.1、API介紹

localStorage 和 sessionStorage 提供了相同的方法進行存儲、檢索和刪除。常用的方法如下:

  1. 設置數據:setItem(key, value)

存儲的值可以是字符串、數字、布爾、數組和對象。對象和數組必須轉換為 string 進行存儲。JSON.parse() 和 JSON.stringify() 方法可以將數組、對象等值類型轉換為字符串類型,從而存儲到 Storage 中;

localStorage.setItem("username", "name"); // "name"
localStorage.setItem("count", 1); // "1"
localStorage.setItem("isOnline", true); // "true"
sessionStorage.setItem("username", "name");
// user 存儲時,先使用 JSON 序列化,否則保存的是[object Object]
const user = { "username": "name" };
localStorage.setItem("user", JSON.stringify(user));
sessionStorage.setItem("user", JSON.stringify(user));

eg:數據沒有序列化,導致保存的數據異常

圖片圖片

  1. 獲取數據:getItem(key)

如果 key 對應的 value 獲取不到,則返回值是 null;

const usernameLocal = localStorage.getItem("username");
const usernameSession = sessionStorage.getItem("username");
// 獲取到的數據為string,使用時反序列化數據
const userLocal = JSON.parse(localStorage.getItem("user"));
const userSession = JSON.parse(sessionStorage.getItem("user"));
  1. 刪除數據:removeItem(key);
localStorage.removeItem("username");
sessionStorage.removeItem("username");
  1. 清空數據:clear();
localStorage.clear();
sessionStorage.clear();
  1. 在不確定是否存在 key 的情況下,可以使用 hasOwnProperty() 進行檢查;
localStorage.hasOwnProperty("userName"); // true
sessionStorage.hasOwnProperty("userName"); // false
  1. 當然,也可以使用 Object.keys() 查看所有存儲數據的鍵;
Object.keys(localStorage); // ['username']
Object.keys(sessionStorage);

3.2、瀏覽器查看

本地存儲的內容可以在瀏覽器中直接查看,以 Chrome 為例,按住鍵盤 F12 進入開發者工具后,選擇 Application,然后就能在左邊 Storage 列表中找到 localStorage 和 sessionStorgae。

圖片圖片

3.3、監聽

當存儲的數據發生變化時,其他頁面通過監聽 storage 事件,來獲取變更前后的值,以及根據值的變化來處理頁面的展示邏輯。

JS 原生監聽事件,只能夠監聽同源非同一個頁面中的 storage 事件,如果想監聽同一個頁面的,需要改寫原生方法,拋出自定義事件來監聽。具體如下:

  1. 監聽同源非同一個頁面

直接在其他頁面添加監聽事件即可。

eg:同域下的 A、B 兩個頁面,A 修改了 localStorage,B 頁面可以監聽到 storage 事件。

window.addEventListener("storage", () => {
  // 監聽 username 值變化
  if (e.key === "username") {
    console.log("username 舊值:" + e.oldValue + ",新值:" + e.newValue);
  }
})

注:

  • 當兩次 setItem 更新的值一樣時,監聽方法是不會觸發的;
  • storage 事件只能監聽到 localStorage 的變化。
  1. 監聽同一個頁面

重寫 Storage 的 setItem 事件,同理,也可以監聽刪除事件 removeItem 和獲取事件 getItem。

(() => {
  const originalSetItem = localStorage.setItem;
  // 重寫 setItem 函數
  localStorage.setItem = function (key, val) {
    let event = new Event("setItemEvent");
    event.key = key;
    event.newValue = val;
    window.dispatchEvent(event);
    originalSetItem.apply(this, arguments);
  };
})();

window.addEventListener("setItemEvent", function (e) {
  // 監聽 username 值變化
  if (e.key === "username") {
    const oldValue = localStorage.getItem(e.key);
    console.log("username 舊值:" + oldValue + ",新值:" + e.newValue);
  }
});

四、存儲

瀏覽器默認能夠存儲 5M 的數據,但實際上,瀏覽器并不會為其分配特定的存儲空間,而是根據當前瀏覽器的空閑空間來判斷能夠分配多少存儲空間。

4.1、存儲容量

可以使用 Storage 的 length 屬性,對存儲容量進行測算,以 localStorage 為例:

let str = "0123456789";
let temp = "";
// 先生成一個 10KB 的字符串
while (str.length !== 10240) {
  str = str + "0123456789";
}
// 清空
localStorage.clear();
// 計算總量
const computedTotal = () => {
  return new Promise((resolve) => {
    // 往 localStorage 中累積存儲 10KB
    const timer = setInterval(() => {
      try {
        localStorage.setItem("temp", temp);
      } catch (e) {
        // 報錯說明超出最大存儲
        resolve(temp.length / 1024);
        clearInterval(timer);
        // 統計完記得清空
        localStorage.clear();
      }
      temp += str;
    }, 0);
  });
};
// 計算使用量
const computedUse = () => {
  let cache = 0;
  for (let key in localStorage) {
    if (localStorage.hasOwnProperty(key)) {
      cache += localStorage.getItem(key).length;
    }
  }
  return (cache / 1024).toFixed(2);
};

(async () => {
  const total = await computedTotal();
  let use = "0123456789";
  for (let i = 0; i < 1000; i++) {
    use += "0123456789";
  }
  localStorage.setItem("use", use);
  const useCache = computedUse();

  console.log(`最大容量${total}KB`);
  console.log(`已用${useCache}KB`);
  console.log(`剩余可用容量${total - useCache}KB`);
})();

可見在 Chrome 瀏覽器下,localStorage 有 5M 容量。

圖片圖片

4.2、存儲性能

在某些特殊場景下,需要存儲大數據,為了更好的利用 Storage 的存儲空間,可以采取以下解決方案,但不應該過于頻繁地將大量數據存儲在 Storage 中,因為在寫入數據時,會對整個頁面進行阻塞(不推薦這種方式)。

  1. 壓縮數據

可以使用數據壓縮庫對 Storage 中的數據進行壓縮,從而減小數據占用的存儲空間。

eg:使用 lz-string 庫的 compress() 函數將數據進行壓縮,并將壓縮后的數據存儲到 localStorage 中。

const LZString = require("lz-string");
const data = "This is a test message";
// 壓縮
const compressedData = LZString.compress(data);
localStorage.setItem("test", compressedData);
// 解壓
const decompressedData = LZString.decompress(localStorage.getItem("test"));
  1. 分割數據

將大的數據分割成多個小的片段存儲到 Storage 中,從而減小單個數據占用的存儲空間。

eg:將用戶數據分割為單項存儲到 localStorage 中。

for (const key in userInfo) {
  localStorage.setItem(key, userInfo[key]);
}

圖片圖片

  1. 取消不必要的數據存儲

可以在代碼中取消一些不必要的數據存儲,從而減小占用空間。

eg:只存儲用到的用戶名、公司主體和后端所在環境字段信息。

for (const key in userInfo) {
  if (["userName", "legalEntityName", "isOnline"].includes(key)) {
    localStorage.setItem(key, userInfo[key]);
  }
}

圖片圖片

  1. 設置過期時間

localStorage 是不支持過期時間的,在存儲信息過多后,會拖慢瀏覽器速度,也會因為瀏覽器存儲容量不夠而報錯,可以封裝一層邏輯來實現設置過期時間,以達到清理的目的。

// 設置
function set(key, value){
  const time = new Date().getTime(); //獲取當前時間
  localStorage.setItem(key, JSON.stringify({value, time})); //轉換成json字符串
}
// 獲取
function get(key, exp){
  // exp 過期時間
  const value = localStorage.getItem(key); 
  const valueJson = JSON.parse(value); 
  //當前時間 - 存儲的創建時間 > 過期時間
  if(new Date().getTime() - valueJson.time > exp){
    console.log("expires"); //提示過期
  } else {
    console.log("value:" + valueJson.value);
  }
}

五、應用

5.1、使用習慣記錄

用來緩存一些篩選項數據,保存用戶習慣信息,起到避免多次重復操作的作用。

eg:在 beetle 工程列表中,展示了自已權限下所有 beetle 的項目,對于參與項目多和參與項目少的人,操作習慣是不同的,由此,記錄收藏功能狀態解決了這一問題,讓篩選項記住用戶選擇,方便下次使用。

圖片圖片

圖片圖片

在開發使用中,直接獲取 localStorage.getItem('isFavor') 作為默認值展示,切換后使用 localStorage.setItem() 方法更新保存內容。

// 獲取
const isFavor = localStorage.getItem('isFavor');
this.state = {
  isFavor: isFavor !== null ? Number(isFavor) : EngineeringTypeEnum.FAVOR,
};
// 展示默認值
<Form.Item name='isFavor' initialValue={this.state.isFavor}>
  <Select
    placeholder='篩選收藏的工程'
    onChange={(e) => this.changeFavor(e)}
    {...searchSmallFormProps}
  >
      {EngineeringTypeEnum.property.map(e => (<Option key={e.id} value={e.id}>{e.name}</Option>))}
  </Select>
</Form.Item>
// 變更
changeFavor = (e) => {
  localStorage.setItem('isFavor', e);
  this.setState({ isFavor: e });
};

5.2、首次打開提示

用來緩存用戶導覽,尤其是只需要出現一次的操作說明彈窗等。

eg:當第一次或者清空緩存后登錄,頁面需要出現操作指南和用戶手冊的彈窗說明。

圖片圖片

在開發使用中,注意存儲的數據類型為 string,轉成布爾值是為了在插件中方便控制彈窗的顯示隱藏。

// 獲取
const operationVisible = localStorage.getItem('operationVisible');
this.state = {
  operationVisible: operationVisible === null || operationVisible === 'true' ? true : false,
};
// 控制展示
<Modal
  title='操作指南'
  open={this.state.operationVisible}
  onCancel={() => { 
    this.setState({ operationVisible: false }); 
    localStorage.setItem('operationVisible', false); 
  }}
  footer={null}
  destroyOnClose={true}
>
  <Divider orientation='left'>動作</Divider>
  <p>接口 》 用例 》 用例集,3級結構滿足不了后續的使用,因此增加【動作】這一層級,【動作】是接口測試的最小單元,多個【動作】可以組合成一個用例,多個用例可以聚合為用例集;</p>
  <Image src={OperationGuidePng} preview={false} />
</Modal>

5.3、減少重復訪問接口

在瀏覽頁面時,會遇到一些經常訪問但返回數據不更新的接口,這種特別適合用做頁面緩存,只在頁面打開的時候訪問一次,其他時間獲取緩存數據即可。

eg:在我們的一些內部系統中,用戶信息是每個頁面都要用到的,尤其是 userId 字段,會與每個獲取數據接口掛鉤,但這個數據是不會變的,一直請求是沒有意義的,為減少接口的訪問次數,可以將主要數據緩存在 localStorage 內,方便其他接口獲取。

六、總結

希望通過此篇文章,可以讓大家了解 Web Storage 在瀏覽器數據存儲和讀取的相關操作,以及相關事件和限制。

它可以用于保存用戶的偏好設置、表單數據等,在開發中使用可以方便的存儲和讀取數據,提高用戶體驗。當然,在使用時需要特別注意它的限制,以及在存儲、讀取和刪除數據過程中的錯誤處理。


關于作者

劉筱雨,轉轉工程效率組內成員,主要負責公司內部公共系統前端項目。

責任編輯:武曉燕 來源: 轉轉QA
相關推薦

2020-12-29 09:56:29

瀏覽器緩存HTTP

2023-11-27 17:35:48

ComponentWeb外層

2019-12-17 14:45:17

瀏覽器事件循環前端

2021-05-07 14:03:36

大數據存儲接口CSI

2022-09-21 09:04:07

Python裝飾器

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智領云

2025-02-11 09:29:07

2022-09-22 09:00:46

CSS單位

2018-09-28 14:06:25

前端緩存后端

2025-04-03 10:56:47

2022-11-06 21:14:02

數據驅動架構數據

2019-11-05 10:47:16

Python框架服務器

2024-09-03 08:40:31

2022-07-05 06:30:54

云網絡網絡云原生

2023-05-20 17:58:31

低代碼軟件

2022-07-26 00:00:03

語言模型人工智能

2022-10-20 08:01:23

2021-12-29 18:00:19

無損網絡網絡通信網絡

2022-12-01 17:23:45

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99re热精品视频 | 美国一级黄色片 | 韩国久久 | 色网站在线 | 精品国产第一区二区三区 | 91电影在线播放 | 天堂影院av| 国产美女黄色 | 国产高清在线视频 | 欧美一区二区三区在线观看 | 鲁大师一区影视 | 午夜影视网| 久久精品国产亚洲 | 欧美性a视频 | 亚洲aⅴ精品 | 91精品国产91 | 欧美啪啪 | 日韩a| 欧美不卡| 久久中文字幕视频 | 久久躁日日躁aaaaxxxx | www精品美女久久久tv | 久久之精品| 久久久99国产精品免费 | 精久久 | 亚洲一区二区在线视频 | 999精品视频在线观看 | 男人天堂网址 | 久久不卡 | av在线一区二区三区 | 精品国产乱码久久久久久闺蜜 | 欧美成人不卡 | 精品久久久久久亚洲综合网站 | 亚洲色图在线观看 | 日韩不卡一区二区三区 | 亚洲精品一区二区 | 日本不卡一区二区三区 | 激情av网站 | 夜夜爽99久久国产综合精品女不卡 | 蜜臀久久99精品久久久久野外 | av三级在线观看 |