经验笔记:Web 浏览器存储手段

Web 浏览器存储手段经验笔记

在 Web 开发中,数据存储是一项至关重要的任务。不同的存储手段适用于不同的场景,选择合适的存储方案对于提高用户体验、减轻服务器负载等方面有着重要作用。以下是几种常见的 Web 浏览器存储手段及其特点:

1 Cookies
  • 用途:Cookies 最初设计用于会话管理,例如记录用户的登录状态或购物车内容。

  • 特点

    • 存储容量有限(大约 4KB/域名)。
    • 每次请求时都会随 HTTP 头发送给服务器,可能导致带宽浪费。
    • 可以设置有效期、路径、安全标志(HTTPS)、HttpOnly 标志(防止 XSS 攻击)。
  • 应用场景:用户认证、会话管理等。

  • 在Web中使用Cookies

    在 Web 浏览器中使用 Cookies 是一种常见的做法,用于跟踪用户的会话状态或其他信息。Cookies 是小段文本数据,由服务器发送给浏览器,浏览器将其存储在用户的计算机上,并且在后续的请求中自动将 Cookies 发送回服务器。下面是一个关于如何在 Web 浏览器中设置和使用 Cookies 的指南。

    1.1 设置 Cookies

    在 JavaScript 中,可以通过 document.cookie 属性来设置和获取 Cookies。下面是一个简单的示例,展示如何设置一个 Cookie:

    function setCookie(name, value, days) {
       var expires = "";
       if (days) {
          var date = new Date();
          date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
          expires = "; expires=" + date.toUTCString();
       }
       document.cookie = name + "=" + (value || "") + expires + "; path=/";
    }
    

    此函数接受三个参数:

    • name: Cookie 的名称。
    • value: Cookie 的值。
    • days: Cookie 的有效期(天数)。如果未指定,则默认为会话 Cookie,即关闭浏览器后删除。
    1.2 获取 Cookies

    从 JavaScript 中读取 Cookies 的值稍微复杂一些,因为 document.cookie 返回的是一个字符串,其中包含所有 Cookies 的信息,格式如下:

    name1=value1; name2=value2; ...
    

    可以通过解析这个字符串来获取特定的 Cookie 值:

    function getCookie(name) {
       var nameEQ = name + "=";
       var ca = document.cookie.split(';');
       for(var i=0;i < ca.length;i++) {
          var c = ca[i];
          while (c.charAt(0)==' ') c = c.substring(1,c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
       }
       return null;
    }
    
    1.3 删除 Cookies

    删除一个 Cookie 实际上是通过设置该 Cookie 的过期时间为过去的一个时间点来实现的:

    function deleteCookie(name) {
       document.cookie = name + '=; Max-Age=-99999999;';
    }
    
    1.4 设置其他 Cookie 属性

    除了基本的设置外,还可以为 Cookie 添加其他属性,例如 pathdomainsecureHttpOnly

    function setCookieWithAttributes(name, value, days, path, domain, secure) {
       var expires = "";
       if (days) {
          var date = new Date();
          date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
          expires = "; expires=" + date.toUTCString();
       }
       document.cookie = name + "=" + (value || "") + expires +
                         "; path=" + (path || "/") +
                         "; domain=" + (domain || "") +
                         "; secure=" + (secure || false) +
                         "; HttpOnly";
    }
    
    1.5 使用 Cookies 的注意事项
    • 安全性:为了防止跨站脚本攻击(XSS),应该为敏感的 Cookies 设置 HttpOnly 标志。
    • 隐私:避免在 Cookies 中存储敏感信息,并且确保遵守相关的隐私法律。
    • 大小限制:单个 Cookie 的大小不应超过 4KB,否则可能不会被完全存储或传输。
    1.6 使用 Cookies的示例

    下面是一个完整的示例,展示了如何设置、获取和删除一个 Cookie:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Cookie Example</title>
    <script>
    function setCookie(name, value, days) {
       var expires = "";
       if (days) {
          var date = new Date();
          date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
          expires = "; expires=" + date.toUTCString();
       }
       document.cookie = name + "=" + (value || "") + expires + "; path=/";
    }
    
    function getCookie(name) {
       var nameEQ = name + "=";
       var ca = document.cookie.split(';');
       for(var i=0;i < ca.length;i++) {
          var c = ca[i];
          while (c.charAt(0)==' ') c = c.substring(1,c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
       }
       return null;
    }
    
    function deleteCookie(name) {
       document.cookie = name + '=; Max-Age=-999999999;';
    }
    
    window.onload = function() {
       // 设置一个名为 'username' 的 Cookie
       setCookie('username', 'JohnDoe', 365);
    
       // 获取 'username' Cookie 的值
       var username = getCookie('username');
       console.log('Username:', username);
    
       // 删除 'username' Cookie
       deleteCookie('username');
    };
    </script>
    </head>
    <body>
    <p>This is an example of using cookies in JavaScript.</p>
    </body>
    </html>
    

    通过上述代码,你可以理解如何在 Web 应用程序中使用 Cookies 来存储和读取信息。不过需要注意的是,随着隐私保护意识的增强,过度依赖 Cookies 可能会影响用户体验和数据安全,因此在设计应用程序时应考虑使用其他存储技术作为补充。

2 SessionStorage 和 LocalStorage
  • 用途:HTML5 引入的 Web 存储 API,用于在客户端存储数据。

  • 特点

    • 存储容量较大(通常为 5MB 左右)。
    • SessionStorage 数据只在一个会话期间有效,关闭窗口后清除。
    • LocalStorage 数据持久化存储,除非用户清除或通过 JavaScript 删除。
  • 应用场景:存储应用状态、偏好设置等非敏感数据。

  • 在Web中使用SessionStorage 和 LocalStorage

    在 Web 浏览器中使用 SessionStorageLocalStorage 是非常直接的。这两种存储技术都是 HTML5 Web Storage API 的一部分,提供了简单的方式来在客户端存储数据。下面是使用这两种存储方式的一些基本示例。

    2.1 SessionStorage

    SessionStorage 用于存储与单一浏览器会话相关的信息。这意味着当用户关闭浏览器窗口或标签页时,存储的数据就会被删除。

    2.2 设置 SessionStorage
    // 设置 SessionStorage 的一个键值对
    sessionStorage.setItem('key', 'value');
    
    // 读取 SessionStorage 中的数据
    var value = sessionStorage.getItem('key');
    console.log(value);  // 输出 'value'
    
    // 删除 SessionStorage 中的一个键值对
    sessionStorage.removeItem('key');
    
    // 清空整个 SessionStorage
    sessionStorage.clear();
    
    2.3 LocalStorage

    LocalStorage 用于持久地存储数据。即使用户关闭浏览器或计算机,数据也会一直存在,直到用户或脚本显式地删除它们。

    2.4 设置 LocalStorage
    // 设置 LocalStorage 的一个键值对
    localStorage.setItem('key', 'value');
    
    // 读取 LocalStorage 中的数据
    var value = localStorage.getItem('key');
    console.log(value);  // 输出 'value'
    
    // 删除 LocalStorage 中的一个键值对
    localStorage.removeItem('key');
    
    // 清空整个 LocalStorage
    localStorage.clear();
    
    2.5 SessionStorage与LocalStorage使用示例

    下面是一个简单的 HTML 页面,演示了如何使用 SessionStorageLocalStorage 来存储和检索数据:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <title>Web Storage 示例</title>
    <script>
    function saveData(storageType) {
       var storage = storageType === 'session' ? sessionStorage : localStorage;
       storage.setItem('exampleKey', 'exampleValue');
       alert('数据已保存!');
    }
    
    function retrieveData(storageType) {
       var storage = storageType === 'session' ? sessionStorage : localStorage;
       var value = storage.getItem('exampleKey');
       if (value) {
          alert('检索到的数据: ' + value);
       } else {
          alert('没有找到数据。');
       }
    }
    
    function removeData(storageType) {
       var storage = storageType === 'session' ? sessionStorage : localStorage;
       storage.removeItem('exampleKey');
       alert('数据已删除!');
    }
    
    function clearAll(storageType) {
       var storage = storageType === 'session' ? sessionStorage : localStorage;
       storage.clear();
       alert('所有数据已清空!');
    }
    </script>
    </head>
    <body>
    <h1>Web Storage 示例</h1>
    <button onclick="saveData('local')">保存至 LocalStorage</button>
    <button onclick="retrieveData('local')">从 LocalStorage 检索</button>
    <button onclick="removeData('local')">从 LocalStorage 删除</button>
    <button onclick="clearAll('local')">清空 LocalStorage</button>
    
    <button onclick="saveData('session')">保存至 SessionStorage</button>
    <button onclick="retrieveData('session')">从 SessionStorage 检索</button>
    <button onclick="removeData('session')">从 SessionStorage 删除</button>
    <button onclick="clearAll('session')">清空 SessionStorage</button>
    </body>
    </html>
    

    在这个示例中,我们定义了四个按钮,分别用于保存、检索、删除和清空 LocalStorageSessionStorage 中的数据。点击这些按钮会触发相应的 JavaScript 函数,从而执行相应的操作。

    2.6 SessionStorage与LocalStorage-注意事项
    • 安全性:虽然 LocalStorageSessionStorage 是客户端存储,但它们并不是私密的。任何在同一站点上下文中的脚本都可以访问这些数据。因此,不要将敏感信息存储在这里。
      • 为什么 LocalStorageSessionStorage 不是私密的?
        • 跨脚本访问:在同一域名下的所有脚本都可以访问 LocalStorageSessionStorage 中的数据。如果一个网站受到 XSS 攻击,攻击者可以通过注入恶意脚本来窃取这些数据。
        • 持久性LocalStorage 是持久化的存储,数据不会随着浏览器会话结束而消失。这意味着如果用户在公共计算机上使用了一个网站,然后离开而没有清理浏览器数据,其他人可以访问这些数据。
        • 不支持 HttpOnly 标志:与 Cookies 不同,LocalStorageSessionStorage 不支持 HttpOnly 标志,这意味着 JavaScript 代码可以轻松地读取这些数据,增加了被恶意脚本访问的风险。
    • 存储限制:尽管 LocalStorageSessionStorage 的存储空间相对较大(通常为 5MB 左右),但仍然有限制。超出限制会导致数据无法保存。
    • 兼容性:尽管大多数现代浏览器都支持 LocalStorageSessionStorage,但在一些较旧的浏览器或特殊环境下可能不支持。在使用之前检查浏览器的兼容性是很重要的。

    通过上述示例和说明,你应该能够开始在 Web 应用程序中有效地使用 LocalStorageSessionStorage 来存储和管理客户端数据了。

3 IndexedDB
  • 用途:一种低级 API,用于在客户端存储大量结构化数据。

  • 特点

    • 支持事务处理、索引和复杂的查询能力。
    • 存储容量非常大,理论上没有固定限制。
    • 数据存储在对象存储区中,可以通过键路径或索引访问。
  • 应用场景:离线应用、大型数据集存储、需要高性能读写的应用。

  • 在Web中使用IndexedDB

    在 Web 浏览器中使用 IndexedDB 可以让你存储大量的结构化数据,并且提供了事务处理的能力。下面是一个简单的示例,展示如何在浏览器中使用 IndexedDB。

    3.1 创建 IndexedDB 数据库

    首先,你需要打开一个数据库连接。如果数据库不存在,IndexedDB 会自动创建它。以下是一个基本的例子:

    // 打开或创建数据库
    const request = indexedDB.open("myDatabase", 1); // 第一个参数是数据库名,第二个参数是版本号
    
    request.onerror = function(event) {
       console.error('Database error: ' + event.target.errorCode);
    };
    
    request.onsuccess = function(event) {
       const db = event.target.result;
       // 数据库已经打开,可以开始使用
       // 注意:不要在此事件处理函数之外保留对 db 对象的引用
    };
    
    request.onupgradeneeded = function(event) {
       const db = event.target.result;
       // 这里可以创建对象存储区和索引
       const objectStore = db.createObjectStore("objectStoreName", { keyPath: "id" });
    };
    
    3.2 IndexedDB-在对象存储区中添加数据

    一旦数据库打开并准备就绪,你可以开始添加、更新或删除数据。以下是一个添加数据的简单例子:

    function addData(db, data) {
       const transaction = db.transaction(["objectStoreName"], "readwrite");
       const objectStore = transaction.objectStore("objectStoreName");
    
       transaction.oncomplete = function(event) {
          console.log('Transaction completed.');
       };
    
       transaction.onerror = function(event) {
          console.error('Transaction error: ' + event.target.errorCode);
       };
    
       const request = objectStore.add(data);
    
       request.onsuccess = function(event) {
          console.log('Data added to database.');
       };
    
       request.onerror = function(event) {
          console.error('Error adding data: ' + event.target.errorCode);
       };
    }
    
    3.3 IndexedDB-从对象存储区获取数据

    获取数据可以通过键值来检索,也可以通过范围来检索。这里是一个通过键值获取数据的例子:

    function getData(db, key) {
       const transaction = db.transaction(["objectStoreName"], "readonly");
       const objectStore = transaction.objectStore("objectStoreName");
    
       const request = objectStore.get(key);
    
       request.onsuccess = function(event) {
          if (request.result) {
                console.log('Retrieved data: ', request.result);
          } else {
                console.log('No data found with the specified key.');
          }
       };
    
       request.onerror = function(event) {
          console.error('Error retrieving data: ' + event.target.errorCode);
       };
    }
    
    3.4 IndexedDB-删除数据

    删除数据同样需要一个事务:

    function deleteData(db, key) {
       const transaction = db.transaction(["objectStoreName"], "readwrite");
       const objectStore = transaction.objectStore("objectStoreName");
    
       const request = objectStore.delete(key);
    
       request.onsuccess = function(event) {
          console.log('Data deleted.');
       };
    
       request.onerror = function(event) {
          console.error('Error deleting data: ' + event.target.errorCode);
       };
    }
    
    3.5 IndexedDB-进行事务处理

    IndexedDB 使用事务来保证数据的一致性和完整性。在上面的例子中,每次对数据库的操作都是在一个事务上下文中完成的。

    3.6 在Web中使用IndexedDB-总结

    以上就是使用 IndexedDB 的基本步骤。IndexedDB 提供了强大的数据存储能力,并且可以通过索引来优化数据检索性能。在实际应用中,可能还需要处理更复杂的场景,比如数据迁移、错误处理等。务必确保你的代码能够妥善处理各种异常情况。

4 Web SQL (已废弃)
  • 用途:虽然曾经用于创建和操作 SQLite 数据库,但现在已被废弃。
  • 特点
    • 仅在部分浏览器中支持,如基于 Chromium 的浏览器。
    • 缺乏标准化,不推荐使用。
  • 应用场景:不建议使用。
5 Service Worker Cache API
  • 用途:用于存储响应和资源副本,支持离线使用。

  • 特点

    • 可以缓存网络请求的响应。
    • 适合用于缓存静态资源或动态内容。
  • 应用场景:离线应用、减少加载时间、增强用户体验。

  • 在Web中使用Service Worker Cache API

    Service Worker Cache API 是一种用于在客户端缓存资源的技术,它允许你在离线情况下使用网页应用。通过 Service Worker Cache API,你可以存储响应和资源副本,从而在没有网络连接的情况下也能访问这些资源。以下是使用 Service Worker Cache API 的基本步骤。

    5.1 注册 Service Worker

    首先,你需要注册一个 Service Worker。Service Worker 是一个运行在浏览器后台的 JavaScript 文件,它可以拦截网络请求,并且控制页面的行为。

    if ('serviceWorker' in navigator) {
       window.addEventListener('load', function() {
          navigator.serviceWorker.register('/service-worker.js').then(function(registration) {
                console.log('Service Worker registered with scope:', registration.scope);
          }).catch(function(err) {
                console.error('Service Worker registration failed:', err);
          });
       });
    }
    
    5.2 Service Worker-缓存资源

    在 Service Worker 脚本中,你可以使用 Cache API 来缓存资源。以下是一个 Service Worker 脚本的基本结构:

    self.addEventListener('install', function(event) {
       event.waitUntil(
          caches.open('v1').then(function(cache) {
                return cache.addAll([
                   '/',
                   '/index.html',
                   '/styles.css',
                   '/script.js',
                   // 添加更多需要缓存的资源
                ]);
          })
       );
    });
    
    self.addEventListener('fetch', function(event) {
       event.respondWith(
          caches.match(event.request).then(function(response) {
                return response || fetch(event.request);
          })
       );
    });
    
    5.2.1 Service Worker-缓存资源-解释
    • install 事件:当 Service Worker 安装时触发。这是初始化缓存的好时机。
    • caches.open 方法:打开或创建一个缓存。v1 是缓存的名字,可以根据需要更改。
    • cache.addAll 方法:向缓存中添加一系列 URL。这些 URL 指向需要缓存的资源。
    • fetch 事件:当 Service Worker 拦截到一个请求时触发。这里我们可以检查缓存中是否有请求的资源。
    • caches.match 方法:查找缓存中是否有对应的请求。如果有,则返回缓存响应;如果没有,则通过 fetch 请求资源。
    5.3 Service Worker-更新缓存

    当你需要更新缓存时,可以改变缓存的版本号,并在新的 install 事件中缓存新的资源列表。

    self.addEventListener('activate', function(event) {
       event.waitUntil(
          caches.keys().then(function(cacheNames) {
                return Promise.all(
                   cacheNames.map(function(cacheName) {
                      if (cacheName !== 'v1') {
                            return caches.delete(cacheName);
                      }
                   })
                );
          })
       );
    });
    
    5.3.1 Service Worker-更新缓存-解释
    • activate 事件:当 Service Worker 激活时触发。这是清理旧缓存的好时机。
    • caches.keys 方法:返回所有缓存的名称。
    • caches.delete 方法:删除指定的缓存。
    5.4 Service Worker-使用缓存

    当用户访问页面时,如果 Service Worker 已经激活并且资源已经被缓存,那么这些资源可以直接从缓存中读取,无需网络请求。

    5.5 Service Worker-示例完整代码

    下面是一个完整的 Service Worker 脚本示例:

    self.addEventListener('install', function(event) {
       event.waitUntil(
          caches.open('v1').then(function(cache) {
                return cache.addAll([
                   '/',
                   '/index.html',
                   '/styles.css',
                   '/script.js'
                ]);
          })
       );
    });
    
    self.addEventListener('fetch', function(event) {
       event.respondWith(
          caches.match(event.request).then(function(response) {
                return response || fetch(event.request);
          })
       );
    });
    
    self.addEventListener('activate', function(event) {
       event.waitUntil(
          caches.keys().then(function(cacheNames) {
                return Promise.all(
                   cacheNames.map(function(cacheName) {
                      if (cacheName !== 'v1') {
                            return caches.delete(cacheName);
                      }
                   })
                );
          })
       );
    });
    
    5.6 Service Worker Cache API-注意事项
    • 版本管理:确保每次更新资源时也更新缓存的版本号,以确保旧缓存被替换。
    • 资源更新:如果你修改了某个资源的内容,记得更新其 URL(例如,通过添加哈希值),以确保 Service Worker 会缓存新版本。
    • 调试工具:使用浏览器开发者工具中的 Application 面板来查看和管理缓存。

    通过以上的步骤,你可以利用 Service Worker Cache API 来提升你的 Web 应用的性能,并使其能够在离线模式下工作。

6 选择合适的存储手段

选择适当的存储手段时,需要考虑以下几个因素:

  • 数据量:对于少量数据,可以选择 Cookies 或 LocalStorage。
  • 持久性:如果数据需要持久化存储,应使用 LocalStorage 或 IndexedDB。
  • 结构化需求:需要存储复杂数据结构时,IndexedDB 是最佳选择。
  • 安全性:对于敏感数据,应使用 HttpOnly Cookies 或加密数据。
  • 跨域共享:如果需要跨域共享数据,可以考虑使用 Shared Workers。
7 结论

每种存储手段都有其独特的优点和局限性。在开发过程中,根据具体需求选择合适的存储技术至关重要。同时,随着技术的发展,新的存储技术可能会出现,因此保持对新技术的关注也是必要的。正确使用 Web 存储手段不仅能提升应用的性能,还能增强用户体验。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值