Cookie、本地存储、会话存储
我们很多人都听说过会话存储、本地存储和 Cookie。但它们到底是什么,它们解决什么问题,它们有何不同?
Cookie
一开始,网络使用 HTTP 协议来发送消息(顺便说一句,SSL 更安全,您应该使用 HTTPS 而不是 HTTP)。这些协议是无状态协议。在无状态协议中,每个请求不存储任何状态或“持久信息”;每个请求都是它自己的岛屿,它不知道其他请求。
采用无状态协议可以优化性能,但它也带来了一个问题:如果您需要记住用户会话怎么办?如果您有darkMode: true或user_uuid: 12345abc,如果您使用无状态协议,服务器如何记住它?带着Cookie!
可以从 HTTP 标头设置 Cookie。通常,您尝试访问的服务器(如果有 cookie)将发送如下 HTTP 标头:
Set-Cookie: choco_chip_cookie=its_delicious
当您的浏览器收到此标头时,它会保存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;
您可能需要了解的另一种 Cookie 行为:您的浏览器在每次请求时发送 Cookie 。当您访问时https://example.com,您必须发出 30 次请求才能下载 HTML 页面及其 29 个资产文件,您的浏览器将发送您的 Cookie(针对https://example.com域名) 30 次,每个请求发送一次。
这仅适用于您将资产存储在同一域名下的情况,例如
example.com/assets/images/cute-cats.svg、
example.com/assets/stylesheets/widgets.css等。如果您将资产存储在不同的域/子域下,例如
exampleassets.com/assets/stylesheets/widgets.css或
static.example.com/assets/stylesheets/widgets.css,那么您的浏览器将不会向那里发送 Cookie。仅供参考,将您的资产存储在不同的域中是提高速度的好策略!
Cookie 的最大大小为 4kb。这是有道理的,因为 Cookie 一直在发送。您不想在访问页面时向所有 30 个不同的请求发送 3mb Cookie 数据。即使有这个大小上限,您也应该尽可能减少 Cookie 以减少流量。
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 / 任何现代浏览器访问任何网页(确保它使用 Cookie)。
- 查看您当前拥有的 cookie。
- 现在查看“网络”选项卡并检查请求标头。您应该会看到发送相同的 Cookie。
您可以使用 Javascript 创建 cookie document.cookie。
document.cookie = "choco_chip_cookie=its_delicious";
document.cookie = "choco_donut=its_awesome";
console.log(document.cookie);
除了 之外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
一般来说,如果您有疑问,请使用Secure和HttpOnlyCookie 属性。
本地存储和会话存储
本地存储和会话存储的相似之处多于不同之处。大多数现代浏览器应该支持本地存储和会话存储功能。它们用于在浏览器中存储数据。它们只能从客户端访问(Web 服务器无法直接访问它们)。此外,由于它们是前端工具,因此不支持 SSL。
与 Cookie 不同,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;
您还可以将类似 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
如果您有 Chrome,您可以在 devtool 应用程序选项卡 -> 存储 -> 本地存储中看到您刚刚输入的 localStorage 值。如果您有 Firefox,则可以在开发工具中的“存储”选项卡中的“本地存储”下找到它。
使用 Javascript 访问会话存储与本地存储类似:
sessionStorage.setItem('strawberry', 'pancake');
sessionStorage.getItems('strawberry'); // pancake`
sessionStorage.chocolate = 'waffle';
sessionStorage.chocolate; // waffle
sessionStorage['blueberry'] = 'donut';
sessionStorage['blueberry']; // donut;
delete sessionStorage.strawberry;
与 Cookie 一样,这两种存储的范围都仅限于域名。如果您运行localStorage.setItem('choco', 'donut');于https://example.com且运行localStorage.setItem('choco', 'bo');于https://whatever.com,则本地存储项choco donut仅存储于example.com,而choco bo存储于whatever.com。
本地存储和会话存储均由浏览器供应商确定范围。如果您使用 Chrome 存储它,则无法从 Firefox 读取它。
Cookie、本地存储、会话存储
总结一下:
Cookie
- 具有不同的过期日期(服务器或客户端都可以设置过期日期)
- HttpOnly如果该标志为 true,则客户端无法访问 Cookie
- 有 SSL 支持
- 每个 HTTP 请求都会传输数据
- 4kb 限制
本地存储
- 没有有效期
- 仅限客户
- 不支持 SSL
- 数据不会在每个 HTTP 请求上传输
- 5 mb 限制(通过浏览器检查)
会话存储
- 关闭浏览器选项卡后数据就会消失
- 仅限客户
- 不支持 SSL
- 数据不会在每个 HTTP 请求上传输
- 5-10 mb 限制(通过浏览器检查)