JoJ*_*oJo 78 javascript subdomain local-storage
我正在用支持它的浏览器(除了IE之外的任何人)用localStorage替换cookie .问题是site.com和www.site.com存储自己独立的localStorage对象.我相信www被认为是一个子域名(如果你问我,这是一个愚蠢的决定).如果用户最初在site.com上并决定输入www.site.com在下次访问时,她的所有个人数据都将无法访问.如何让所有"子域"与主域共享相同的localStorage?
May*_*ain 79
这就是我跨域使用它的方式......
我希望它有帮助:)
Mat*_*att 32
如果您仅针对此特定问题使用iframe和postMessage解决方案,我认为将数据存储在无子域的cookie中可能不那么有效(在代码方面和计算方面),如果它还没有在localStorage上加载,从cookie中获取它.
我同意其他评论者,这似乎应该是localStorage的可指定选项,因此不需要解决方法.
URL*_*L87 14
在主域中设置为 cookie -
document.cookie = "key=value;domain=.mydomain.com"
Run Code Online (Sandbox Code Playgroud)
然后从任何主域或子域中获取数据并将其设置在 localStorage 上
[ 2020 年 11 月更新: 此解决方案依赖于能够设置document.domain. 不幸的是,现在已经弃用了这样做的能力。]
为了在给定超级域(例如 example.com)的子域之间共享,您可以在这种情况下使用一种技术。它可以应用到localStorage,IndexedDB,SharedWorker,BroadcastChannel,等等,所有这些都提供相同来源的网页之间共享的功能,但由于某种原因不尊重任何修改document.domain,将让他们直接使用一个超级原籍。
(1) 为数据选择一个“主”域:即https://example.com或https://www.example.com将保存您的 localStorage 数据。假设您选择https://example.com。
(2) 通常为所选域的页面使用 localStorage。
(3) 在所有https://www.example.com页面(其他域)上,使用 javascript 设置document.domain = "example.com";. 然后还创建一个 hidden <iframe>,并将其导航到所选https://example.com域上的某个页面(哪个页面无关紧要,只要您可以在那里插入一小段 javascript。如果您重新创建站点,只需为此目的专门创建一个空页面。如果您正在编写扩展程序或 Greasemonkey 样式的用户脚本,因此对example.com上的页面没有任何控制权服务器,只需选择您能找到的最轻量级的页面并将您的脚本插入其中。某种“未找到”页面可能没问题)。
(4) 隐藏的 iframe 页面上的脚本只需要 (a) 设置document.domain = "example.com";,和 (b) 完成后通知父窗口。之后,父窗口可以不受限制地访问 iframe 窗口及其所有对象!所以最小的 iframe 页面是这样的:
<!doctype html>
<html>
<head>
<script>
document.domain = "example.com";
window.parent.iframeReady(); // function defined & called on parent window
</script>
</head>
<body></body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果编写用户脚本,您可能不想添加外部可访问的函数,例如iframeReady()您的unsafeWindow,因此通知主窗口用户脚本的更好方法可能是使用自定义事件:
window.parent.dispatchEvent(new CustomEvent("iframeReady"));
Run Code Online (Sandbox Code Playgroud)
您可以通过将自定义“iframeReady”事件的侦听器添加到主页窗口来检测。
(注意:即使 iframe 的域已经是example.com,您也需要设置 document.domain = "example.com" :为 document.domain 分配一个值隐式地将源的端口设置为 null,并且两个端口都必须与 iframe 匹配及其父级被视为同源。请参阅此处的注释:https : //developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin)
(5)一旦隐藏的iframe已通知它的父窗口,它已经准备好,在父窗口脚本可以直接使用iframe.contentWindow.localStorage,iframe.contentWindow.indexedDB,iframe.contentWindow.BroadcastChannel,iframe.contentWindow.SharedWorker而不是window.localStorage,window.indexedDB等等......所有这些对象将范围限定于选择https://开头example.com来源 - 因此他们将为您的所有页面拥有相同的共享来源!
这项技术最尴尬的部分是您必须等待 iframe 加载才能继续。因此,例如,您不能在 DOMContentLoaded 处理程序中轻松地开始使用 localStorage。此外,您可能想要添加一些错误处理来检测隐藏的 iframe 是否无法正确加载。
显然,您还应该确保在页面的生命周期内不会删除或导航隐藏的 iframe... OTOH 我不知道结果会是什么,但很可能会发生不好的事情。
并且,需要注意的是:document.domain可以使用标头阻止设置/更改Feature-Policy,在这种情况下,该技术将无法如所述使用。
然而,这种技术有一个明显更复杂的概括,它不能被 阻止Feature-Policy,并且还允许完全不相关的域共享数据、通信和共享工作器(即不仅仅是公共超级域的子域)。@Mayank Jain 已经在他们的回答中描述了它,即:
一般的想法是,就像上面一样,您创建一个隐藏的 iframe 来提供正确的访问来源;但不是直接获取 iframe 窗口的属性,而是在 iframe 内使用脚本来完成所有工作,并且仅使用postMessage()和在 iframe 和主窗口之间进行通信addEventListener("message",...)。
这是有效的,因为postMessage()甚至可以在不同来源的窗口之间使用。但它也更加复杂,因为您必须通过在 iframe 和主窗口之间创建的某种消息传递基础结构传递所有内容,而不是直接在主窗口的代码中使用 localStorage、IndexedDB 等 API。
| 归档时间: |
|
| 查看次数: |
75479 次 |
| 最近记录: |