天天看點

在App hybrid多webView視窗中實作 sessionStorage

需求背景

在App hybrid多webView視窗中實作 sessionStorage

業務中需要根據定位擷取周邊的位置點,定位功能包括自動擷取定位和手動切換定位,産品希望在 App 關閉之前都使用手動切換的定位。總結就是需要把使用者手動切換過的定位資訊存儲起來

技術背景

  • App webView
  • H5

*App 中為了實作滑動傳回上一頁的翻頁效果,每次路由跳轉都是打開一個新的 webview,就像一疊撲克牌

hybrid開發中會打開多個webView 頁面,頁面A設定資料,頁面B中要得知資料,如果使用redux狀态管理器、或浏覽器sessionStorage在目前webView tab視窗有效,但關閉或打開新的視窗即銷毀,在新的webView視窗如何擷取資料 *

問題描述

這樣就導緻以下問題:

  • store 不再是真正的全局 store,隻是目前頁面的 store
  • 跨頁面通信需要借助 App 的廣播來實作(例如填寫位址場景)
  • 頁面需要借助 App 的在頁面再次顯示時更新資料(例如購物車場景)
  • sessionStorage 不可用

解決思路

  • 通過 App UA 中的 sid 結合 localStorage 來模拟 sessionStorage,App UA: (window.navigator.userAgent)
Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 app_name/gaia app_ac/7c1d8e0a-a463-4428-b270-37410df888ae app_version/4.18.0 app_system_version/14.4 app_client_id/974CDCF679DD49959A2B908B55AFF47E app_sid/039C2702-C9E1-44DC-9C1D-F859B0CD75CB

代碼實作

/**
 * @description 擷取sid (在app關閉重新打開才會改變)
 */
export const getHybridSid = () => {
  return navigator.userAgent.match(/app_sid\/([0-9|a-z|\-|]+)/i)?.[1];
};

/**
 * 判斷是否重新打開了app相對上次的存SessionStorage值
 */
const isReopenForSessionStorage = () => {
  const app_sid = getHybridSid();
  const app_sid_last = window.localStorage.getItem('hybridSidForSessionStorage');
  return !(app_sid_last && app_sid === app_sid_last);
};

/**
 * @description 相容APP和H5的sessionStorage 擷取
 * @param key 擷取參數的key值
 */
export const getSessionStorage = (key) => {
  if (isHybridEnv()) {
    if (isReopenForSessionStorage()) {
      localStorage.setItem(key, null);
      return null;
    } else {
      return localStorage.getItem(key);
    }
  } else {
    return sessionStorage.getItem(key);
  }
};

/**
 * @description 相容APP和H5的sessionStorage 設定
 * @param key 設定參數的key值
 * @param value 設定的值
 */
export const setSessionStorage = (key, value) => {
  if (isHybridEnv()) {
    localStorage.setItem('hybridSidForSessionStorage', getHybridSid());
    return localStorage.setItem(key, value);
  } else {
    return sessionStorage.setItem(key, value);
  }
};


           

繼續閱讀