Cookies、本地存储和会话存储

2025-05-27

Cookies、本地存储和会话存储

我们很多人都听说过会话存储、本地存储和 Cookie。但它们到底是什么?它们解决了什么问题?它们之间又有什么区别?

曲奇饼

最初,Web 使用 HTTP 协议发送消息(顺便说一句,SSL 更安全,你应该使用 HTTPS 而不是 HTTP)。这些协议是无状态协议。在无状态协议中,每个请求不存储任何状态或“持久信息”;每个请求都是一个独立的“孤岛”,它不知道其他请求的存在。

无状态协议可以优化性能,但也存在一个问题:如果需要记住用户会话怎么办?如果使用无状态协议darkMode: trueuser_uuid: 12345abc服务器该如何记住?答案是:用 Cookies!

Cookie 可以通过 HTTP 头设置。通常,如果你尝试访问的服务器有 Cookie,它会发送如下 HTTP 头:

Set-Cookie: choco_chip_cookie=its_delicious
Enter fullscreen mode Exit fullscreen mode

当您的浏览器收到此标头时,它会保存choco_chip_cookieCookie。

Cookie 与网站关联。如果您websitea.com启用了,则您在 时cookie_a无法查看。您需要在cookie_awebsiteb.comwebsitea.com

要查看你拥有的 Cookie,如果你使用的是 Firefox,请在开发者工具中前往“存储”->“Cookie”;如果你使用的是 Chrome,请在开发者工具中前往“应用程序”->“存储”->“Cookie”。大多数网站都使用 Cookie,你应该能在那里找到一些(如果没有,请前往其他网站)。

Cookie 可以设置有效期。当然​​,你可以将其设置为一个遥远的未来日期,使其永久有效:

Set-Cookie: choco_chip_cookie=its_delicious; Expires=Mon, 28 Feb 2100 23:59:59GMT;
Enter fullscreen mode Exit fullscreen mode

您可能需要了解的另一个 Cookie 行为是:您的浏览器在每次请求时都会发送 Cookie 。当您访问时https://example.com,需要发出 30 个请求来下载 HTML 页面及其 29 个资源文件,您的浏览器将发送您的 Cookie(针对https://example.com域名)30 次,每次请求一个。

这仅适用于您将资源存储在相同域名下的情况,例如example.com/assets/images/cute-cats.svgexample.com/assets/stylesheets/widgets.css等。如果您将资源存储在不同的域名/子域名下,例如exampleassets.com/assets/stylesheets/widgets.cssstatic.example.com/assets/stylesheets/widgets.css,则浏览器将不会向该域名发送 Cookie。仅供参考,将资源存储在不同的域名是提高速度的好策略!

Cookies 的最大大小为 4KB。这是合理的,因为 Cookies 会一直被发送。您肯定不希望在访问一个页面时向所有 30 个不同的请求发送 3MB 的 Cookie 数据。即使有这个大小上限,您也应该尽可能减少 Cookies 数量以减少流量。

Cookie 的一个常见用法是,为您的网站使用一个 UUID,并运行一个单独的服务器来存储所有 UUID,以保存会话信息。单独的 Redis 服务器是一个不错的选择,因为它速度很快。因此,当用户尝试访问 时example.com/user_settings,该用户会发送其 Cookie example.com,例如example_site_uuid=user_iggy_uuid,然后您的服务器会读取该 Cookie,然后您的服务器可以将其与 Redis 中的键匹配,以获取用户会话信息供服务器使用。在您的 Redis 服务器中,您将获得类似 的内容user_iggy_uuid: {darkMode: false, lastVisit: 01 January 2010, autoPayment: false, ...}

我强烈建议你亲自体验一下。使用 Chrome/Firefox 或任何现代浏览器访问任意网页(确保它启用了 Cookies)。

  • 查看您当前拥有的 cookie。
  • 现在查看“网络”选项卡并检查请求标头。您应该看到相同的 Cookie 被发送。

您可以使用 Javascript 创建 cookie document.cookie

document.cookie = "choco_chip_cookie=its_delicious";
document.cookie = "choco_donut=its_awesome";
console.log(document.cookie);
Enter fullscreen mode Exit fullscreen mode

除此之外Expires,Cookie 还有很多其他属性,您可以赋予它们来执行各种操作。如果您想了解更多信息,请查看Mozilla Cookie 页面

Cookie 可以被第三方访问(例如,如果网站使用 HTTP 而不是 HTTPS),因此您需要使用该Secure属性来确保仅在请求使用 HTTPS 协议时发送 Cookie。此外,使用该HttpOnly属性可以使您的 Cookie 无法访问,document.cookie从而防止 XSS 攻击。

Set-Cookie: awesome_uuid=abc12345; Expires=Thu, 21 Oct 2100 11:59:59 GMT; Secure; HttpOnly
Enter fullscreen mode Exit fullscreen mode

一般来说,如果您有疑问,请使用SecureHttpOnlyCookie 属性。

本地存储和会话存储

本地存储和会话存储的相似之处多于不同之处。大多数现代浏览器都支持本地存储和会话存储功能。它们用于在浏览器中存储数据。它们只能从客户端访问(Web 服务器无法直接访问它们)。此外,由于它们是前端工具,因此不支持 SSL。

与 Cookie 不同,所有 Cookie(针对该域名)都会在每次请求时发送,而本地存储和会话存储数据则不会在每次 HTTP 请求时发送。它们只是停留在您的浏览器中,直到有人请求为止。

每个浏览器对于本地存储和会话存储的数据量都有不同的规范。许多主流文献声称本地存储的限制约为 5mb,会话存储的限制约为 5-10mb(为了安全起见,请检查每个浏览器)。

本地存储和会话存储之间的主要区别在于,本地存储没有到期日期,而会话存储数据在您关闭浏览器选项卡时就会消失 - 因此称为“会话”。

这两个存储都可以通过 JavaScript DOM 访问。要设置、获取和删除本地存储数据,请执行以下操作:

localStorage.setItem('strawberry', 'pancake');
localStorage.getItems('strawberry'); // pancake`

localStorage.chocolate = 'waffle';
localStorage.chocolate; // waffle

localStorage['blueberry'] = 'donut';
localStorage['blueberry']; // donut;

delete localStorage.strawberry;
Enter fullscreen mode Exit fullscreen mode

您还可以将类似 JSON 的对象存储在本地存储中。请记住,您需要向其传递一个 JSON 字符串(使用JSON.stringify)。另外,由于您传递的是 JSON 字符串,因此请不要忘记运行JSON.parse以获取其值。

localStorage.desserts = JSON.stringify({choco: "waffle", fruit: "pancake", sweet: "donut"});
const favDessert = JSON.parse(localStorage.desserts)['choco']; // waffle
Enter fullscreen mode Exit fullscreen mode

如果您使用的是 Chrome,则可以在 devtool 的“应用程序”选项卡 ->“存储”->“本地存储”中看到刚刚输入的 localStorage 值。如果您使用的是 Firefox,则可以在 devtool 的“存储”选项卡中的“本地存储”下找到它。

使用 Javascript 访问会话存储与访问本地存储类似:

sessionStorage.setItem('strawberry', 'pancake');
sessionStorage.getItems('strawberry'); // pancake`

sessionStorage.chocolate = 'waffle';
sessionStorage.chocolate; // waffle

sessionStorage['blueberry'] = 'donut';
sessionStorage['blueberry']; // donut;

delete sessionStorage.strawberry;
Enter fullscreen mode Exit fullscreen mode

两种存储都与域名相关,就像 Cookies 一样。如果您localStorage.setItem('choco', 'donut');在 中运行,并且在 中https://example.com运行,则本地存储项仅存储在 中,存储在 中localStorage.setItem('choco', 'bo');https://whatever.comchoco donutexample.comchoco bowhatever.com

本地存储和会话存储均由浏览器厂商定义。如果您使用 Chrome 浏览器存储,则无法从 Firefox 读取。

Cookies、本地存储和会话存储

总结一下:

曲奇饼

  • 有不同的到期日期(服务器或客户端都可以设置到期日期)
  • HttpOnly如果该标志为真,则客户端无法访问 Cookies
  • 具有 SSL 支持
  • 每次 HTTP 请求时都会传输数据
  • 4kb 限制

本地存储

  • 没有有效期
  • 仅限客户端
  • 不支持 SSL
  • 每次 HTTP 请求时都不会传输数据
  • 5mb 限制(请通过浏览器检查)

会话存储

  • 关闭浏览器标签页时数据就会消失
  • 仅限客户端
  • 不支持 SSL
  • 每次 HTTP 请求时都不会传输数据
  • 5-10 mb 限制(请通过浏览器检查)
文章来源:https://dev.to/iggredible/cookies-vs-local-storage-vs-session-storage-3gp3
PREV
每个新开发人员都应该收藏的 7 篇有用文章👍💯目录
NEXT
Git 和 GitHub:完整指南 - 第 4 章:分支