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

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

(1)使用 storage 事件:localStoragesessionStorage 对象都会触发 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 对象来代理localStoragesessionStorage,可以拦截对存储的读写操作,并在变化时执行自定义的操作。

// 监听存储变化的封装函数function addStorageListener(storageType, callback) {// 根据存储类型选择 localStorage 或 sessionStoragevar 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)封装自定义函数:使用自定义的封装函数来检测 localStoragesessionStorage 的变化,您可以创建一个函数,该函数在存储值发生变化时被调用,并通过监听 storage 事件来触发回调函数。

// 监听存储变化的封装函数function addStorageListener(storageType, callback) {// 根据存储类型选择 localStorage 或 sessionStoragevar 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  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页通信

// 设置cookiedocument.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