你听说 chrome 最新引入的特性 ”unpartitioned third-party storage“ 了么?

chrome 在 115 版本引入了一个和 iframe 息息相关的新特性,叫做 unpartitioned third-party storage,虽然不是什么重大更新,但是这个还真有可能一不小心给我们的工作埋下暗坑,如果你项目里用到 iframe 集成其他项目的页面了,还正好涉及到了一些单点登录相关的功能,那为了避免喜提来自 chrome 的工作量,咱还是来了解一下比较好。

这是个什么东西?

首先我们要知道的是,在老版本的 chrome 中,localstorage 的访问只和所处页面是否同源有关,只要地址是同源的,比如 example.com。那么无论你访问的是下面哪种情况:

这三个 example.com 读写的 localstorage 实际上是通用的,我们可以写一个 demo 证明一下。

由于这个特性是默认开启的,所以如果你的版本大于 115 的话,就需要先访问 chrome://flagsExperimental third-party storage partitioning 设置为 Disabled。

假设我们有两个网站,b.html 长这样,它可以更新 localstorage 里一个名为 token 的字段。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>网站B</title>
</head>

<body>
  <h1>网站B</h1>
  <button id="update-btn">刷新 token</button>
  <button id="open-btn">新标签页打开网站B</button>
  <p id="show">当前 localstorage 中 token 的值为:</p>
  <input placeholder="设置 localstorage token" id="my-input" />
  <button id="save-btn">保存</button>
</body>
<script>
  const readLocalstorage = () => {
    const value = localStorage.getItem('token')
    document.getElementById('show').innerText = `当前 localstorage 中 token 的值为:${value}`
  }

  document.getElementById('save-btn').addEventListener('click', () => {
    const value = document.getElementById('my-input').value
    localStorage.setItem('token', value)
    readLocalstorage();
  })

  document.getElementById('open-btn').addEventListener('click', () => {
    window.open('http://localhost:9876', '__blank');
  })

  document.getElementById('update-btn').addEventListener('click', () => {
    readLocalstorage();
  })

  readLocalstorage();
</script>
</html>

以及 a.thml,它只是单纯的用 iframe 集成了 b.html:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网站A</title>
</head>
<body>
  <h1>网站A</h1>
  <iframe src="http://localhost:9876" style="height: 100vh;width: 80vw;"></iframe>
</body>
</html>

现在我们用 serve 分别把 a.html 暴露在 127.0.0.1:9875,把 b.html 暴露在 127.0.0.1:9876。然后访问一下 a.html:

可以看到,不管有没有被 iframe 嵌套,127.0.0.1:9876 中的 b.html 始终可以访问到自己域下的最新 localstorage。

那如果把 Experimental third-party storage partitioning. 打开呢?

iframe 里边的 b.html 和直接标签页打开的 b.html 能访问到的 localstorage 被隔离开了,它们两个访问到的不再是同一个,而是各自独立的 localstorage。

开启了 Experimental third-party storage partitioning,被 iframe 集成的网站的域会变成类似于 a.com/b.com,而直接打开的网站的域则是 b.com,两者互相独立。

关于这个特性的官方介绍在 Participate in deprecation trial for unpartitioned third-party storage, Service Workers, and Communication APIs - Chrome for Developers

会导致什么问题?

现在可以回想一下,你项目里有没有用 iframe 接入过其他项目的某个页面,并且当外部页面登录之后,会通过单点使得 iframe 里边的页面也完成登录。

如果有的话,那 iframe 里的页面如果执行了类似于 window.open 的操作,那大概率就会触发这个问题。

具体表现就是:本来我操作的页面(嵌在 iframe 里)是已经登录的,但是当打开一个新窗口后,突然弹回到登录页了。明明原来的页面登录状态还没有掉,新开的窗口页为什么一直提示未登录呢。

原因很简单,前端的登录状态一般都是通过把 token 保存在 localstorage 里实现的。而新开的窗口页无法访问到 iframe 里保存的 localstorage token 字段。就认为系统未登录了。

怎么解决?

有三种方案,第一种是临时过渡方案:参考 这里的方法

根据你的情况从对应的链接里申请一个 token,然后放在你的网站上。之后这个检查就会被临时解除。但是要注意,最晚到 2024 年 9 月 4 号,这个方案就会被彻底关闭(这个实验特性被实装),所以你需要评估一下。

第二种方案要求你能修改 iframe 内嵌网站的代码,判断自己是否被 iframe 集成了,如果是的话就不在跳转,而是对外 postmessage,让 iframe 外边的网站再走一遍单点流程然后 window.open 就行了。

第三种方案就是通过 nginx 反代,把 iframe 里边集成的项目跟你外部的项目搞成同源的,这就彻底没这个问题了,但是改造成本可能不低。你可能得处理诸如字体、图片、接口请求、前端静态资源等一系列加载问题。

一些细节

当一个嵌在 iframe 里的页面触发了这个特性时,在 localstorage 里会将其标注为 is-third-party

并且,这个特性的触发标准是 top-level origin,而不是我们所熟知的同源策略 same-site origin。所以你可以发现哪怕端口不同(不同源),我们实际上也不会触发这个特性:

参考

相关推荐
Defry3 小时前
Selenium WebDriver和Chrome对照表
chrome·selenium·测试工具
风清扬_jd17 小时前
Chromium 中JavaScript Fetch API接口c++代码实现(二)
javascript·c++·chrome
BigYe程普1 天前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
风清扬_jd1 天前
Chromium 添加书签功能浅析c++
c++·chrome
风清扬_jd1 天前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
ConardLi2 天前
Chrome:新的滚动捕捉事件助你实现更丝滑的动画效果!
前端·javascript·浏览器
cuisidong19972 天前
如何在 Kali Linux 上安装 Google Chrome 浏览器
linux·运维·chrome
哈哈哈哈cwl2 天前
一篇打通浏览器储存
前端·面试·浏览器
守城小轩2 天前
Brave编译指南2024 MacOS篇-构建与运行(六)
chrome·chrome devtools·指纹浏览器·浏览器开发·brave
浏览器爱好者4 天前
怎么在Windows系统中使用Chrome的语音搜索功能
前端·chrome