首次引入cookie时,它??们是浏览器保存数据的唯一方式。然后有许多新选项:WebStorageAPI、IndexedDB和CacheAPI。那么饼干死了吗?让我们来看看这些在浏览器中存储数据的技术。Cookies是由服务器发送或设置在客户端,并存储在用户本地浏览器中的信息单元。它们会自动附加到每个请求。由于HTTP是一种无状态协议,因此cookie允许将信息存储在客户端上,以便将额外的上下文数据传递给服务器。Cookie具有一些有助于提高数据安全性的标志。HttpOnly标志阻止JavaScript访问cookie,并且只有在附加到HTTP请求时才能访问它们。这对于防止通过XSS(跨站点脚本)攻击造成的数据泄露非常有用。此外,Secure标志确保仅在通过HTTPS协议发送请求时才发送cookie。SameSite标志可以设置为lax或strict(请在此处查看它们的区别),可用于帮助防止CSRF(跨站点请求伪造)请求。它告诉浏览器仅在请求发送到与请求者位于同一域的URL时才发送cookie。什么时候使用cookie?那么,你想什么时候得到饼干?最常见的用例之一是授权令牌。由于HttpOnly标志添加了额外的保护层以防止XSS攻击,SameSite可防止CSRF,而Secure可确保您的cookie已加密,从而为您的身份验证令牌提供额外的保护层。由于authtoken很小,您不必担心请求太大。此外,由于它们会自动附加到每个请求,使用cookie可以在服务器上确定用户是否已通过身份验证。这对于服务器呈现的内容很有用,例如,如果您想将未经身份验证的用户重定向到登录页面。cookie的另一个用途是存储用户的语言代码。由于您可能希望在大多数请求中访问用户的语言,因此您可以利用它来自动附加。如何使用cookie?现在我们已经讨论了使用cookie的原因,让我们看看如何使用它们。要从服务器向客户端设置cookie,请将Set-Cookie标头添加到HTTP响应。Cookie的格式应为key=value。如果您在Node.js应用程序中设置cookie,您的代码可能如下所示:response.setHeader('Set-Cookie',['user_lang=en-us','user_theme=dark_mode']);这将设置两个cookie:它将user_lang设置为en-us,将user_theme设置为dark_mode。Cookies也可以被客户操纵。要设置cookie,请以key=value的格式为document.cookie分配一个值。如果密钥已经存在,它将被覆盖。document.cookie='user_lang=es-es';如果已定义user_lang,则它现在等于es-es。您可以通过访问document.cookie值来查看所有cookie。这将返回一串以分号分隔的键值对。document.cookie='user_lang=en-us';document.cookie='user_theme=light_mode';console.log(document.cookie);//'user_lang=en-us;user_theme=light_mode;'添加key-value对可访问性,可以使用以下函数将此字符串解析为对象:constparseCookies=x=>x.split(';').map(e=>e.trim().split('='))。reduce((obj,[key,value])=>({...obj,[key]:value}),{});如果您需要将其中一个标志设置到您的cookie上,您可以在之后添加它们一个分号。例如,如果您想在cookie上设置Secure和SameSite标志,您可以执行以下操作:例如,如果您想在cookie上设置Secure和SameSite标志,您可以执行以下操作:cookie='product_ids=123,321;secure;samesite=lax'由于HTTPOnly的作用是让cookie只能在服务端访问,所以只能由服务端添加。除了这些安全标志之外,您还可以设置Max-Age(cookie应保留的秒数)或Expires(cookie应过期的日期)。如果这些都没有设置,cookie将在浏览器会话期间跟随。如果用户使用隐身模式,当用户的会话关闭时,cookie将被删除。由于处理cookie的接口不是很友好,可以使用js-cookie等库来方便其操作。WebStorageAPIWebStorageAPI是一种用于在本地存储数据的新选项。它是在HTML5中添加的,WebStorageAPI包括localStorage和sessionStorage。虽然cookie通常处理服务器/客户端通信,但WebStorageAPI最适合保存客户端数据。我们已经有cookie作为本地存储数据的选项,为什么我们需要网络存储?原因之一:由于cookie会自动添加到每个HTTP请求中,因此请求大小可能会变得臃肿。因此,您可以使用WebStorageAPI来存储比cookie大得多的数据量。另一个优势是更直观的API。如果使用cookie,您需要手动解析cookie字符串以访问各个键。WebStorage使这更容易。如果要设置或获取一个值,可以使用setItem或getItem。localStorage.setItem('selected_tab','FAQ');localSTorage.getItem('selected_tab');//'FAQ'键和值必须是字符串。如果你想保存一个对象或数组,你可以通过在保存时调用JSON.stringify()和在读取时调用JSON.parse()来实现。constproduct={id:'123',name:'CoffeeBeans',};localStorage.setItem('cached_product',JSON.stringify(product));JSON.parse(localStorage.getItem('cached_product'));本地存储的另一个用例是在多个选项卡之间同步数据。您可以通过为“存储”事件添加侦听器来更新另一个选项卡或窗口中的数据。window.addEventListener('storage',()=>{console.log('localstoragehasbeenupdated');});只有在另一个文档中修改本地或会话存储时才会触发此事件。也就是说,您无法监听当前浏览器选项卡中的存储更改。不幸的是,在撰写本文时,Chrome尚不支持存储事件侦听器。那么localStorage和sessionStorage有什么区别呢?与cookie不同,WebStorageAPI没有过期或最长期限功能。如果使用localStorage,除非手动删除,否则数据将无限期保留。您可以通过运行localStorage.removeItem('key')删除单个键的值,或通过运行localStorage.clear()清除所有数据。如果使用sessionStorage,数据只会持续到当前会话结束。如果您没有设置最长时间或过期时间,它将被视为与cookie的持久性类似。在任何一种情况下,如果用户使用隐身模式,本地存储都不会在会话之间保留数据。IndexedDB如果cookies和localStorage都不符合你的要求,还有一个选择:IndexedDB,浏览器内置的数据库系统。localStorage同步执行所有方法,而IndexedDB异步调用它们。这将允许在不阻塞其余代码的情况下访问数据。当您处理大量访问成本高昂的代码时,这非常有用。IndexedDB在其存储的数据类型方面也具有更大的灵活性。虽然cookie和localStorage仅限于存储字符串,但IndexedDB可以存储可以通过“结构化克隆算法”复制的任何类型的数据。这包括对象、日期、文件、Blob、RegEx和更多类型。性能和灵活性提高的缺点是IndexedDB的API级别较低且更复杂。幸运的是,有很多库可以解决这个问题。localForage为IndexedDB提供了一个更简单的类似localStorage的API。PouchDB提供了一个可以与在线CouchDB数据库同步的离线存储API。idb是一个小型库,具有更简单的基于承诺的API。Dexie在保持良好性能的同时添加了更强大的查询API。根据您的用例,有很多选项。缓存API另一个用于持久数据的专用工具是缓存API。虽然它最初是为服务工作者创建的,但它可以用于缓存任何网络请求。CacheAPI公开了Window.caches,它提供了保存和检索响应的方法,允许您保存成对的请求和响应,以后可以永远访问这些请求和响应。例如,如果您想在从API请求响应之前检查浏览器的缓存以获取响应,您可以这样做:constapiRequest=newRequest('https://www.example.com/items');caches.open('exampleCache')//opensthecache.then(cache=>{cache.match(apiRequest)//checksiftherequestiscached.then(cachedResponse=>cachedResponse||//returncachedReponseifavailablefetch(apiRequest)//否则,makenewrequest.then(response=>{cache.put(apiRequest,response);//cachetheresponsereturnresponse;})}).then(res=>console.log(res))})代码第一次运行时,它会缓存响应。以后每次都会缓存请求,并且不会发出网络请求。总结在浏览器上存储数据的每种方法都有其自身的目的。如果信息较小、敏感且可能在服务器上使用,则Cookie是最佳选择。如果您想保存更大且不太敏感的数据,WebStorageAPI可能是更好的选择。如果您计划存储大量结构化数据,IndexedDB非常适合。CacheAPI用于存储来自HTTP请求的响应。根据您的需要,有许多可用的工具。
