我有
example.com
,它托管一个 iframe 到 app.example.com/signup
。每当 app.example.com/signup
加载时,我想从 iframe 中为 app.example.com
设置一个 localStorage 项目:
---------------------------------------
| example.com |
| |
| ___________________________ |
| | app.example.com/signup | |
| | (iframe) | |
| | | |
| | 'coupon': 'discount30' | |
| |_________________________| |
|_____________________________________|
example.com
代码:
<iframe src="https://app.example.com/signup"></iframe>
app.example.com/signup
代码:
<script>
localStorage.setItem('coupon', 'discount30');
</script>
// Signup form
然后,当我转到
app.example.com
(不是/signup
)时,我希望能够访问我之前从 iframe 中创建的 storageItem
---------------------------------------
| app.example.com |
| |
| 'coupon' localStorage does not exist|
|_____________________________________|
但看起来它没有持久化(或者我无法访问它);虽然 iframe
app.example.com/signup
和 app.example.com
共享相同的域。
我遇到的最密切相关的问题是这个:Safari 和 Safari 移动版上的 Iframe localStorage
这是 Safari 中的预期行为。 Safari 的智能跟踪预防 (ITP) 分区 基于顶部框架的浏览器存储(cookie、localStorage 等)。 这是 WebKit 文档的解释:
分区是一项允许第三方使用存储和有状态 Web 功能的技术,但将这些功能与第一方网站隔离。假设 adtech.example 是 news.example 和 blog.example 下的第三方,并且 adtech.example 使用 LocalStorage。通过分区 LocalStorage,adtech.example 将在 news.example 和 blog.example 下获得唯一的存储实例,从而消除了通过 LocalStorage 进行跨站点跟踪的可能性。
本例中没有提及,但如果用户直接访问
adtech.example
,那么它与news.example
和blog.example
是不同的域,因此ITP将为其提供一个新的存储实例。
这对您来说意味着
app.example.com
在由用户直接加载以及在 example.com
上的 iframe 内加载时具有不同的存储实例。
ITP 可以在 Safari 的偏好设置中关闭,但默认情况下是打开的,因此假设此应用程序将由外部客户使用,Safari 上的大多数用户都会将其打开。
Safari 提供了 Storage Access API,您可以使用它来解决此问题。 来自 WebKit 的博文:
解决方案是允许第三方嵌入在用户与第三方嵌入交互时请求访问其第一方 cookie。为此,我们创建了存储访问 API。