作者:Adam Giese
翻译:疯狂的技术宅
原文:https://blog.logrocket.com/beyond-cookies-todays-options-for-client-side-data-storage/未经允许严禁转载

当 cookie 被首次引入时,它是浏览器保存数据的唯一方式。之后又有了很多新的选择:Web Storage API、IndexedDB 和 Cache API。那么 cookie 死了吗?我们来看看这些在浏览器中存储数据的技术。

Cookies

Cookie 是由服务器发送或在客户端上设置的信息单位,保存在用户的本地浏览器上。它们会自动附加到每个请求上。由于 HTTP 是无状态协议,因此 cookie 允许将信息存储在客户端上,以便将其他上下文数据传给该服务器。

Cookie 有一些标志,对于提高数据的安全性非常有用。 HttpOnly 标志阻止用 JavaScript 访问 cookie 的行为,只有附加在 HTTP 请求上时才能访问它们。这非常适合防止通过 XSS(跨站点脚本)攻击造成数据泄露。

此外,Secure 标志确保仅在通过 HTTPS 协议发送请求时才发送 cookie。 SameSite 标志,可以设置为 laxstrict(它们的差异看这里),可用于帮助防止 CSRF(跨站点请求伪造)请求。它告诉浏览器只有在请求是与请求者在同一域中的 URL 时才发送 cookie。

什么时候使用 cookies?

那么,在哪些情况下你希望获得 Cookie?最常见的应用场景之一是授权 token 。由于 HttpOnly 标志为 XSS 攻击添加了额外的保护层,SameSite 可以防止 CSRF,而 Secure 可以确保你的 cookie 被加密,这使你的身份验证token 有额外的保护层。

由于 auth token 非常小,因此你无需担心请求过大。此外由于它们会自动附加到每个请求,因此使用 cookie 可以在服务器上确定用户是否经过身份验证。这对于服务器呈现的内容非常有用,例如你希望将未经过身份验证的用户重定向到登录页面。

Cookie 的另一个用途是存储用户的语言代码。由于你可能希望在大多数请求中访问用户的语言,因此你可以利用它自动附加。

如何使用 cookies?

前面经讨论了要使用 cookie 的原因,现在来看看你可以如何使用 cookie。要从服务器上给客户端设置 cookie,需要在 HTTP 响应中添加 Set-Cookie 标头。 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

Cookie 也可以由客户端操纵。要设置 cookie,可以用 key=value 的格式为 document.cookie 赋值。如果 key 已存在,则会被覆盖掉。

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;'

要增加键值对的可访问性,可以使用以下函数将此字符串解析为对象:

const parseCookies = x => x.split(';').map(e => e.trim().split('=')).reduce((obj, [key, value]) => ({...obj, [key]: value}), {});

If you need to set one of the flags onto your cookie, you can add them after a semicolon. For example, if you’d like to set the Secure and SameSite flags onto your cookie, you would do the following:

如果你需要将其中一个标志设置到 cookie 上,可以在分号后添加它们。例如你想在 Cookie 上设置 SecureSameSite 标志,则可以执行以下操作:

document.cookie = 'product_ids=123,321;secure;samesite=lax'

由于 HTTPOnly 的作用是使 cookie 只能在服务器上访问,因此它只能由服务器添加。

除了这些安全标志之外,你还可以设置 Max-Age( cookie 应该保存的秒数)或 Expires(Cookie应该过期的日期)。如果这些都未设置,则 cookie 将跟随浏览器会话的持续时间。如果用户使用隐身模式,则会在用户会话关闭时删除 Cookie。

由于处理 cookie 的接口不是很友好,所以你可以使用诸如 js-cookie 之类的库来方便对其的操作。

Web Storage API

Web Storage API 是一种在本地存储数据的新选项。它在 HTML5 中中添加,Web Storage API 包括localStoragesessionStorage。虽然 cookie 通常处理 server/client 通信,但 Web Storage API 最适用于保存客户端数据。

我们已经将 cookie 作为在本地存储数据的选项,为什么还需要 Web 存储?其中一个原因是:由于 cookie 会自动添加到每个 HTTP 请求中,因此请求大小会变得臃肿。所以你可以用 Web Storage API 存储比 cookie 更大量的数据。

另一个优点是更直观的 API。如果使用 cookie,你需要手动解析 cookie 字符串来访问各个键。 Web Storage 使这更加容易。如果要设置或获取值,可以使用 setItemgetItem

localStorage.setItem('selected_tab', 'FAQ');
localSTorage.getItem('selected_tab'); // 'FAQ'

键和值都必须是字符串。如果你想保存一个对象或数组,可以在保存时调用 JSON.stringify() 并在读取时调用 JSON.parse() 来实现。

const product = {id: '123',name: 'Coffee Beans',
};localStorage.setItem('cached_product', JSON.stringify(product));
JSON.parse(localStorage.getItem('cached_product'));

local storage 的另一个用例是在多个选项卡之间同步数据。通过为 'storage' 事件添加侦听器,你可以在另一个选项卡或窗口中更新数据。

window.addEventListener('storage', () => {console.log('local storage has been updated');
});

仅当在另一个文档中修改本地或会话存储时才会触发此事件。也就是说,你无法在当前浏览器选项卡中侦听 storage 的更改。不幸的是,截至撰写本文时,存储事件监听器尚未在 Chrome 上得到支持。

那么localStoragesessionStorage 之间有什么区别呢?与 cookie 不同,Web Storage API 没有过期或最大期限功能。如果使用 localStorage,除非手动删除,否则数据将无限期保留。你可以通过运行 localStorage.removeItem('key') 来删除单个键的值,或者通过运行 localStorage.clear() 清除所有数据。

如果使用 sessionStorage,则数据将仅持续到当前会话结束。如果你没有设置最大时间或过期,它将被视为与 cookie 保持的方式相似。在任何一种情况下,如果用户使用隐身,本地存储都不会在会话之间保留数据。

IndexedDB

如果 cookie 和 localStorage 都不符合你的要求,还有另一种选择:IndexedDB,一个浏览器内置的数据库系统。

localStorage 同步执行所有方法时,IndexedDB 会异步调用它们。这将会允许访问数据而不会阻塞其余代码。当你处理大量可能访问代价高昂的代码时,这非常有用。

IndexedDB 在其存储的数据类型方面也具有更大的灵活性。虽然 cookies 和 localStorage 仅限于存储字符串,但 IndexedDB 可以存储可以通过“结构化克隆算法”复制的任何类型的数据。这包括 ObjectDateFileBlobRegEx 以及更多类型。

性能和灵活性增加的缺点是 IndexedDB 的 API 更低级且更复杂。幸运的是有许多库可以解决这个问题。

localForage 为 IndexedDB 提供了一个更简单的类似 localStorage 的 API。 PouchDB 提供了一个可以离线的存储 API,可以与在线 CouchDB 数据库同步。 idb 是一个小型库,具有更简单的基于 promise 的 API。 Dexie 添加了更强大的查询 API,同时保持了良好的性能。根据你的使用情况还有许多选择。

Cache API

另一种用于持久数据的专用工具是 Cache API。虽然它最初是为 service workers 创建的,但它可用于缓存任何网络请求。 Cache API 公开了 Window.caches,它提供了保存和检索响应的方法,允许你保存可永远以后访问的 RequestsResponses 对。

例如,如果你想在从 API 请求响应之前检查浏览器的缓存以获取响应,则可以执行以下操作:

const apiRequest = new Request('https://www.example.com/items');
caches.open('exampleCache') // opens the cache.then(cache => {cache.match(apiRequest) // checks if the request is cached.then(cachedResponse => cachedResponse || // return cachedReponse if availablefetch(apiRequest) // otherwise, make new request.then(response => {cache.put(apiRequest, response); // cache the responsereturn response;})}).then(res => console.log(res))
})

第一次运行代码时,它将缓存响应。随后每次都会缓存请求,并且不会发出网络请求。

总结

在浏览器上存储数据的每种方法都有其自己的用途。如果信息很小,很敏感,并且可能在服务器上使用,那么 cookie 就是最佳选择。如果要保存更大且更不敏感的数据,Web Storage API 可能是更好的选择。

如果你打算存储大量结构化数据,IndexedDB 非常棒。 Cache API 用于存储来自 HTTP 请求的响应。根据你的需要,有很多工具可供使用。

其他资源和扩展阅读

你可以通过阅读 MDN 文档来获取更多信息:

  • Web Storage API
  • HTTP cookies
  • IndexedDB API

Cache​developer.mozilla.org

欢迎关注前端公众号:前端先锋,领取前端工程化实用工具包。

es客户端工具_超越 Cookie:当今的客户端数据存储相关推荐

  1. oss客户端工具_阿里云服务器ECS上使用ossfs工具挂载阿里云OSS存储

    介绍:阿里云对象存储服务(Object Storage Service,简称OSS)可以提供基于网络的数据存取服务.使用OSS,可以通过网络随时存储和调用包括文本.图片.音频和视频等在内的各种非结构化 ...

  2. mysql客户端工具_性能优化-理解 MySQL 体系结构(MySQL分库分表)

    实例和数据库 我们通常所说的 MySQL 数据库服务器由一个实例(instance)以及一个数据库(database)组成.实例包括一组后台进程/线程和许多内存结构,用于管理数据库:数据库由一组磁盘文 ...

  3. ubuntu 版mysql客户端工具_使用Ubuntu 20.04作为日常办公主力使用体验(远程维护工具)...

    上次将非常关键的远程网络部分搞定了(使用Ubuntu 20.04作为日常办公主力使用体验(网络配置)),已经具备了基本的维护能力了,接下来就是根据需要安装一些常用工具或替代版本. SSH客户端:Ter ...

  4. oss客户端工具_云享会 | 沃云公有云重点产品推荐:文件存储NASamp;对象存储OSS...

    云享会沃云·公有云重点产品推荐系列 第二期:文件存储NAS和对象存储OSS 还在傻傻分不清文件存储NAS和对象存储OSS? 同样是存储类产品哪个更适合你? 马上为你解答! 文件存储NAS和对象存储OS ...

  5. greenplum客户端工具_首发全新Greenplum数据库图形化客户端

    原标题:首发全新Greenplum数据库图形化客户端 这是一个全新的Greenplum图形化客户端工具,由作者独自全新开发,基本风格布局保持与pgAdmin3一致,以单个可执行exe文件的形式发布,目 ...

  6. 客户端手册_山东省税务局社保费管理客户端企业缴费操作手册

    点击蓝字获取更多精彩信息 一.安装注册 (一)软件安装 运行单位社保费管理客户端安装程序,根据页面提示,可点击"立即安装",软件将开始执行安装操作,安装目录为默认的"C: ...

  7. 汉语句子的意群和重音_五重音而不是字节-数据存储和检索方法

    汉语句子的意群和重音 我们将讨论一种存储和处理信息的方法,并分享有关在此新范例中创建开发平台的一些想法. 做什么的? 要更快地开发并缩短迭代时间:勾画您的项目,确保它符合您的想法,对其进行优化,然后继 ...

  8. 小团队项目管理开源工具_超越指标:如何在当今的开源项目中以团队方式运作

    小团队项目管理开源工具 传统上,我们如何看待社区健康和活力? 我们可能很快将主要涉及代码贡献的指标归零:有多少公司在贡献? 有多少个人? 多少行代码? 总的说来,这既涉及开发活动的水平,也涉及贡献者基 ...

  9. elasticsearch 客户端工具_万字长文:详解 Spring Boot 中操作 ElasticSearch

    点击上方"小强的进阶之路",选择"星标"公众号 优质文章,及时送达 预计阅读时间: 15分钟 一.ElasticSearch 简介 1.简介 ElasticSe ...

最新文章

  1. 自学python能赚钱吗-学习Python多久能找到工作?老男孩Python开发培训
  2. mysql dump xtrabackup_MySQL--备份恢复【Mysqdump+xtrabackup(XBK)】
  3. linux 编译内核几个常见问题解决方法
  4. Hadoop学习很好的书籍,理论和代码都有
  5. 洛谷 - P2763 试题库问题(最大流+路径打印)
  6. ubuntu服务器创建共享文件夹,Ubuntu samba安装创建共享目录及使用
  7. 伪元素::selection -- CSS ::selection 伪元素,定义用户鼠标已选择内容的样式
  8. 非度量多维标度_R软件包vegan教程 2.1非度量多维度标度变换
  9. Java实现对数函数图像增强
  10. 鸿蒙时期电视剧,《我的时代,你的时代》|电视剧简介
  11. 试分别简述udp和tcp的特点_读朱红群《余姚音系简述》
  12. 《人性的弱点》第一章 待人接物的三大原则:读后感
  13. linux设置自动更换壁纸
  14. jvm中关于slot的理解
  15. 2021年中式烹调师(中级)考试报名及中式烹调师(中级)复审模拟考试
  16. angularjs ng-repeat
  17. zw函数和nt函数的区别
  18. 快速搭建Spring BlazeDS Integration框架环境
  19. 使用RandomAccessFile实现多线程下载
  20. 编译报错file format not recognized和collect2: error: ld returned 1 exit status记录

热门文章

  1. 如何查看IIS的80端口被占用?
  2. 来自微软华人的软件人生经历:功夫在身外
  3. npm包的语义版本控制(Semantic Versioning of Packages)
  4. delphi 的插件机制与自动更新
  5. JavaScript之面向对象与原型笔记整理--------创建对象之原型(2)
  6. PHPCMS之 列表和内容页
  7. Git学习05 --分支管理02
  8. poj--3984--迷宫问题(bfs+路径记录)
  9. Hive中分组取前N个值
  10. conda加入pytorch清华源