0

    深入浅出前端本地储存

    2023.07.04 | admin | 122次围观

    引言

    2021 年,如果你的前端应用,需要在浏览器上保存数据,有三个主流方案:

    这些方案就是如今应用最广、浏览器兼容性最高的三种前端储存方案

    今天这篇文章就聊一聊这三种方案的历史,优缺点,以及各自在今天的适用场景

    文章在后面还会提出一个全新的,基于 IndexedDB 的,更适合现代前端应用的前端本地储存方案GoDB.js

    CookieCookie 的历史

    Cookie 早在1994 年就被发明了出来,它的历史甚至和互联网本身的历史一样悠久

    和其它两种本地储存方案不一样的是,Cookie 本身并不是为了解决「在浏览器上存东西」而被发明,它的出现是为了解决 HTTP 协议无状态特性的问题

    什么是 HTTP 协议的无状态特性?简单来说就是:用户的两次 HTTP 请求,服务端并不能通过请求本身,知道这两次请求,来自于同一个用户

    比如我们如今司空见惯的登录功能,在 Cookie 被发明之前其实几乎无法实现登录态的长久保持

    也就是说,Cookie 其实是作为「HTTP 协议的补充」被发明出来的,因此网页保存到本地,在英文语境中,大多时候其实都用HTTP cookie来指 Cookie

    Cookie 最初被其发明者 Lou Montulli 用在电商网站上,用来记录购物车里的商品,这样当用户想要结账时,浏览器会把 Cookie 里的商品数据以及用户信息发送给服务器,服务器就能知道用户想要购买哪些商品

    Cookie 在很长一段时间内,都是浏览器储存数据的唯一解决方案,直到今天,Cookie 在很多领域仍然有大量的使用

    Cookie 的今天

    2021 年,虽然 Cookie 在部分领域仍有不可替代的价值,但其已经不再适合被做为一个前端本地储存方案去使用:

    Cookie 只允许储存 4kb 的数据

    Cookie 的操作较为繁琐复杂(这一点倒是可以通过使用类库来解决)

    有人说由于浏览器每次请求都会带上 Cookie,因此 Cookie 还有个缺点是会增加带宽占用,但其实放在今天的网络环境来看,这点占用基本可以忽略不计

    总之,如今已经不推荐使用 Cookie 来在浏览器上保存数据,大部分曾经应用 Cookie 的场景,在今天都可以用 LocalStorage 实现更优雅更安全的替代

    但是,即使 Cookie 已经不适合用来在浏览器上储存数据,其在某些特定领域,在今天仍然独特的价值

    最常见的就是用在广告中,用来跨站标记用户与跟踪用户行为,这样在你访问不同页面时,广告商也能知道是同一个用户在访问,从而实现后续的商品推荐等功能

    假设abc.com和xyz.com都内嵌了淘宝的广告,你会发现即使abc.com和xyz.com所有者不一致,两个网站上淘宝广告推荐的商品也出奇的一致,这背后是因为淘宝知道是同一个人网页保存到本地,分别在abc.com和xyz.com访问淘宝的广告

    这是如何实现的呢?答案是第三方 Cookie

    第三方 Cookie

    之所以有第三方 Cookie 这个称呼,是因为 Cookie 执行同源策略,a.com和b.com各自只能访问自己的 Cookie,无法访问对方或者任何不属于自己的 Cookie

    如果在访问a.com时,设置了一个b.com的 Cookie(比如内嵌b.com的页面),那么这个 Cookie 相对于a.com而言就是第三方 Cookie

    值得一提的是,是同一个 host 下的不同端口倒是可以互相访问 Cookie

    这里提一下对第三方 Cookie 而言非常重要的一个特性:Cookie 可以被服务端设置

    服务器可以通过 response 的请求头来要求浏览器设置 Cookie

    Set-Cookie: userId=123;

    浏览器在检测到返回请求的 header 里有 Set-Cookie 请求头后,就会自动设置 Cookie,不需要开发者用 JS 去做额外的操作

    这样带来的好处是,当abc.com和xyz.com想在自己的网页上内嵌淘宝广告时,只需要把淘宝提供的组件放进 HTML 即可,不需要写额外的 JS,也能让淘宝进行跨站定位用户

    "taobao.com/some-ads" />

    (这个组件纯属虚构,仅为方便理解)

    它是如何工作的呢?

    当用户处于abc.com时,浏览器会向taobao.com/some-ads发起一个 HTTP 请求

    当淘宝服务器返回广告内容时,会顺带一个Set-Cookie的 HTTP 请求头,告诉浏览器设置一个源为taobao.com的 Cookie,里面存上当前用户的 ID 等信息

    这个 Cookie 相对于abc.com而言就是第三方 Cookie,因为它属于taobao.com

    而当用户访问xyz.com时,由于xyz.com上也嵌入了淘宝的广告,因此用户的浏览器也会向taobao.com/some-ads发起请求

    有意思的来了,发请求时,浏览器发现本地已有taobao.com的 Cookie(此前访问abc.com时设置的),因此,浏览器会将这个 Cookie 发送过去

    淘宝服务器根据发过来的 Cookie,发现当前访问xyz.com的用户和之前访问abc.com的用户是同一个,因此会返回相同的广告

    广告商用第三方 Cookie 来跨站定位用户大概就是这么个过程,实际肯定要复杂许多,但基本原理是一致的

    总之,关键就是利用了 Cookie 的两个特点

    正因为这两个特点,即使 Cookie 在今天看来缺点一大堆,但仍然在部分领域有不可替代的价值

    但也是因为这两个特点,导致 Cookie 的安全性相对不高,总之 Cookie 的这个设计放在今天来看,就是一把双刃剑

    Cookie 配置

    服务端要求浏览器建立 Cookie 时,可以在请求头里放一些配置声明,修改 Cookie 的使用特性

    SameSite

    在前段时间,Chrome 更新 80 版本时,将 Cookie 的跨站策略(SameSite)默认设置为了Lax,即仅允许同站或者子站访问 Cookie,而老版本是None,即允许所有跨站 Cookie

    这会导致用户访问xyz.com时,浏览器默认将不会发送 Cookie 给taobao.com,导致第三方 Cookie 失效的问题

    要解决的话,在返回请求的 header 里将 SameSite 设置为None即可

    Set-Cookie: userId=123; SameSite=None

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论