0


前端存储那些事二

一、两种storage 如何监听他们的变化?

    localStorage

sessionStorage

并没有内置的事件监听机制,因此无法直接监听它们的变化。但是可以使用以下方法实现监听:

(1)使用 storage 事件:

localStorage

sessionStorage

对象都会触发

storage

事件,当其他窗口或标签页对存储进行更改时会触发该事件。您可以通过添加

storage

事件监听器来捕获变化,并在回调函数中执行相应的操作。

// 方法一:监听 storage 事件
window.addEventListener('storage', function(event) {
   if (event.storageArea === localStorage) {
        // localStorage 发生变化
        console.log('localStorage 发生变化');
        console.log('Key发生变化的值是: ' + event.key);
        console.log('New Value发生变化的值是: ' + event.newValue);
    } else if (event.storageArea === sessionStorage) {
         // sessionStorage 发生变化
         console.log('sessionStorage 发生变化');
         console.log('Key发生变化的值是: ' + event.key);
         console.log('New Value发生变化的值是:' + event.newValue);
    }
});

(2)使用定时器:通过使用定时器,在一定的时间间隔内轮询检查存储的值是否发生变化,并在变化时执行相应的操作。

 // 监听 localStorage 变化
 function startLocalStorageListener() {
    // 获取初始的 localStorage 值
    var initialValue = JSON.stringify(localStorage);

    // 每隔一段时间检测 localStorage 是否变化
    setInterval(function() {
        var updatedValue = JSON.stringify(localStorage);
        if (updatedValue !== initialValue) {
          // localStorage 发生变化,执行相应的操作
          console.log("localStorage 发生变化");
          // 更新初始的 localStorage 值
          initialValue = updatedValue;
         }
     }, 1000);
  }

 // 监听 sessionStorage 变化
 function startSessionStorageListener() {
    // 获取初始的 sessionStorage 值
    var initialValue = JSON.stringify(sessionStorage);

    // 每隔一段时间检测 sessionStorage 是否变化
    setInterval(function() {
        var updatedValue = JSON.stringify(sessionStorage);
        if (updatedValue !== initialValue) {
        // sessionStorage 发生变化,执行相应的操作
            console.log("sessionStorage 发生变化");
            // 更新初始的 sessionStorage 值
            initialValue = updatedValue;
            }
     }, 1000); // 检测间隔为1秒
}

// 启动监听
startLocalStorageListener();
startSessionStorageListener();

(3)使用 Proxy 对象:通过创建一个

Proxy

对象来代理

localStorage

sessionStorage

,可以拦截对存储的读写操作,并在变化时执行自定义的操作。

// 监听存储变化的封装函数
function addStorageListener(storageType, callback) {
  // 根据存储类型选择 localStorage 或 sessionStorage
  var storage = (storageType === 'localStorage') ? localStorage : sessionStorage;

  // 创建 Proxy 对象
  var proxy = new Proxy(storage, {
    set: function(target, key, value) {
      // 存储值发生变化,执行回调函数
      callback(key, value);

      // 在实际存储前设置新的值
      target[key] = value;

      return true;
    }
  });
}

// 使用示例
addStorageListener('localStorage', function(key, value) {
  console.log('localStorage 发生改变');
  console.log('Key发生变化的值是: ' + key);
  console.log('Value发生变化的值是: ' + value);
});

addStorageListener('sessionStorage', function(key, value) {
  console.log('sessionStorage 发生改变');
  console.log('Key发生变化的值是: ' + key);
  console.log('Value发生变化的值是: ' + value);
});

(4)封装自定义函数:使用自定义的封装函数来检测

localStorage

sessionStorage

的变化,您可以创建一个函数,该函数在存储值发生变化时被调用,并通过监听

storage

事件来触发回调函数。

// 监听存储变化的封装函数
function addStorageListener(storageType, callback) {
  // 根据存储类型选择 localStorage 或 sessionStorage
  var storage = (storageType === 'localStorage') ? localStorage : sessionStorage;

  // 事件监听器回调函数
  function storageEventListener(event) {
    if (event.storageArea === storage) {
      // 存储值发生变化,执行回调函数
      callback(event.key, event.newValue);
    }
  }

  // 添加事件监听器
  window.addEventListener('storage', storageEventListener);
}

// 使用示例
addStorageListener('localStorage', function(key, value) {
  console.log('localStorage 发生改变');
  console.log('Key发生变化的值是: ' + key);
  console.log('Value发生变化的值是: ' + value);
});

addStorageListener('sessionStorage', function(key, value) {
  console.log('sessionStorage 发生改变');
  console.log('Key发生变化的值是: ' + key);
  console.log('Value发生变化的值是: ' + value);
});

二、如果要给localstorage存储的数据设置过期时间,你会怎么设计技术方案?

(1)手动添加时间戳:在存储数据时,同时将数据和过期时间(时间戳)一起存储。在读取数据时,先检查当前时间是否超过了过期时间,如果是则认为数据已过期,可以进行相应的处理。

// 存储数据到 localStorage,并设置过期时间
function setStorageTime(key, value, time) {
  var dataTime = time * 60 * 1000; // 转换为毫秒
  var item = {
    value: value,
    expiration: Date.now() + dataTime // 当前时间加上过期时间
  };
  localStorage.setItem(key, JSON.stringify(item));
}

// 从 localStorage 读取数据,并检查过期时间
function getStorageTime(key) {
  var item = localStorage.getItem(key);
  if (item) {
    item = JSON.parse(item);
    if (item.expiration && Date.now() > item.expiration) {
      // 数据已过期
      localStorage.removeItem(key);
      return null;
    }
    return item.value;
  }
  return null;
}

// 使用示例
setStorageTime('username', 'Cheng Dong', 10); // 存储数据并设置过期时间为 10 分钟
var username = getStorageTime('username'); // 读取数据
console.log(username); // 输出 'Cheng Dong',如果在 10 分钟内执行,否则输出 null

(2)结合定时器清理过期数据:使用定时器定期检查存储的数据的过期时间,并清理已过期的数据。您可以使用

setInterval

函数设置一个定时器,在固定的时间间隔内检查存储的数据的过期时间,并删除已过期的数据。这样可以保持存储空间的有效利用,同时确保过期数据不会被使用。

// 存储数据到 localStorage,并设置过期时间
function setStorageTime(key, value, time) {
  var dataTime = time * 60 * 1000; // 转换为毫秒
  var item = {
    value: value,
    expiration: Date.now() + dataTime // 当前时间加上过期时间
  };
  localStorage.setItem(key, JSON.stringify(item));
}

// 从 localStorage 读取数据,并检查过期时间
function getStorageTime(key) {
  var item = localStorage.getItem(key);
  if (item) {
    item = JSON.parse(item);
    if (item.expiration && Date.now() > item.expiration) {
      // 数据已过期
      localStorage.removeItem(key);
      return null;
    }
    return item.value;
  }
  return null;
}

// 清理过期数据
function clearDataTime() {
  for (var i = 0; i < localStorage.length; i++) {
    var key = localStorage.key(i);
    var item = localStorage.getItem(key);
    if (item) {
      item = JSON.parse(item);
      if (item.expiration && Date.now() > item.expiration) {
        // 数据已过期,从 localStorage 中移除
        localStorage.removeItem(key);
      }
    }
  }
}

// 设置定时器定期清理过期数据
setInterval(function() {
  clearDataTime();
}, 60 * 1000); // 每分钟清理一次

// 使用示例
setStorageTime('username', 'Cheng Dong', 10); // 存储数据并设置过期时间为 10 分钟
var username = getStorageTime('username'); // 读取数据
console.log(username); // 输出 'Cheng Dong',如果在 10 分钟内执行,否则输出 null

(3)使用自定义封装函数:创建一个封装函数来包装

localStorage

的存储和读取操作,并在其中实现过期时间的逻辑。该函数可以接收一个过期时间参数,并在存储数据时同时存储过期时间。在读取数据时,检查当前时间是否超过了过期时间,如果是则返回空值或默认值。

// 存储数据到 localStorage,并设置过期时间
function setStorageTime(key, value, time) {
  var dataTime = time * 60 * 1000; // 转换为毫秒
  var item = {
    value: value,
    expiration: Date.now() + dataTime // 当前时间加上过期时间
  };
  localStorage.setItem(key, JSON.stringify(item));
}

// 从 localStorage 读取数据,并检查过期时间
function getStorageTime(key) {
  var item = localStorage.getItem(key);
  if (item) {
    item = JSON.parse(item);
    if (item.expiration && Date.now() > item.expiration) {
      // 数据已过期
      localStorage.removeItem(key);
      return null;
    }
    return item.value;
  }
  return null;
}

// 使用示例
setStorageTime('username', 'Cheng Dong', 10); // 存储数据并设置过期时间为 10 分钟
var username = getStorageTime('username'); // 读取数据
console.log(username); // 输出 'Cheng Dong',如果在 10 分钟内执行,否则输出 null

三、用以上提到的api中的一种或几种来实现跨Tab页通信,你会怎么来做?

(1)localStorage实现跨Tab页通信

// 设置
localStorage.setItem('message', '我是localStorage的值');
// 监听使用
window.addEventListener('storage', function(event) {
  if (event.key === 'message') {
    var message = event.newValue;
    console.log('message:', message);
  }
});

(2)sessionStorage实现跨Tab页通信

sessionStorage.setItem('message', '我是sessionStorage的值');
// 触发自定义事件来通知其他标签页
var event = new Event('sessionStorageUpdated');
window.dispatchEvent(event);

window.addEventListener('storage', function(event) {
  if (event.key === 'message') {
    var message = sessionStorage.getItem('message');
    console.log('message:', message);
  }
});

// 监听自定义事件来检测 `sessionStorage` 的更新
window.addEventListener('sessionStorageUpdated', function() {
  var message = sessionStorage.getItem('message');
  console.log('message:', message);
});

(3)cookie实现跨Tab页通信

// 设置cookie
document.cookie = "message = 我是设置的Cookie值";
// 自定义函数
function getCookie(name) {
  var cookies = document.cookie.split(';');
  for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i].trim();
    if (cookie.startsWith(name + "=")) {
      return cookie.substring(name.length + 1);
    }
  }
  return "";
}
// 使用
var message = getCookie("message");
console.log("message:", message);

注:

1、

Cookies

在每个

HTTP

请求中都会被发送到服务器,而不仅仅限于同一浏览器标签页之间,而且会增加网络传输的负担。

2、

Cookies

的大小有限制,一般为几 KB。因此,适用于较小量的数据通信。

3、

Cookies

受浏览器安全问题。

4、

storage

事件只在其他标签页中触发,而在进行写入操作的标签页上不会触发该事件。

5、

localStorage

存储的数据是共享的,因此需要小心处理数据的同步和更新,以避免冲突和数据不一致的问题。

6、

storage

事件在更新同一

sessionStorage

的标签页之间不会触发。

7、

storage

事件无法提供更改的具体值,因此我们需要手动读取

sessionStorage

的值来获取更新的数据。

8、

sessionStorage

实现跨

Tab

页面的通信没有

localStorage

那样直接和简单。

四、cookie是否会导致安全性问题?

cookie

会导致安全性问题:

例如:

1、信息泄露:不适当地处理和存储 Cookie 可能导致敏感信息泄露

解决办法:

  • 仅在必要的情况下存储敏感信息,并在不再需要时立即删除。

  • 使用加密技术来保护敏感信息的存储和传输。

    2、会话劫持:攻击者通过获取合法用户的会话信息,冒充该用户与系统进行交互,从而获取未经授权

    的访问权限或执行恶意操作。

    解决办法:

  • 使用安全的传输层协议(如 HTTPS)来加密会话数据,防止被窃听和篡改。

  • 定期更新会话 Cookie 的值,使攻击者更难截获有效的会话。

    3、跨站点脚本攻击(XSS):攻击者利用该漏洞向目标网站注入恶意脚本代码,从而在用户的浏览器

    中执行恶意代码。

    解决办法:

  • 对用户输入进行验证和过滤,确保不允许注入恶意脚本。

  • 对敏感的 Cookie 设置 Secure 标记,仅在通过 HTTPS 连接时传输。

    4、跨站点请求伪造(CSRF):攻击者通过诱使用户点击恶意链接或访问包含恶意代码的页面,以利用

    用户在目标网站上的已认证会话

    解决办法:

  • 使用 CSRF 令牌(也称为防护令牌)来验证请求的来源和合法性。

  • 在关键操作(如修改或删除数据)上使用 POST 请求而不是 GET 请求。

  • 验证请求的来源,例如检查 Referer 头部。

五、同域名下的

sessionStorage

数据会不会共享

   sessionStorage

的作用域限定在当前会话中,关闭窗口或标签页后数据将被清除。即使是同一域名的不同窗口或者标签,他们之间的

sessionStorage

数据也是相互隔离的,无法直接共享。每个窗口或者标签都有自己独立的

sessionStorage

对象,他们之间的数据互不干扰。

六、不同的子域名之间

cookie

互通吗

    不同的子域名之间
cookie

是不互通的,每个子域名都会被视为不同的域,浏览器会将其视为独立的上下文,各自维护自己的

cookie

标签: 前端

本文转载自: https://blog.csdn.net/m0_52526748/article/details/131308197
版权归原作者 RegularEmployee 所有, 如有侵权,请联系我们删除。

“前端存储那些事二”的评论:

还没有评论