最近将chrome更新到最新的版本,然后发现以前可以正常使用的功能无法使用了,经过分析后发现是浏览器新版本才出现的问题,今天记录以下。
一、遇到的问题
我们具体的问题场景,在A页面中需要打开B页面,同时需要在两个页面之间共享一些数据;
在A页面中我们将共享的数据保存到sessionStorage中,并新建超链接元素并触发其单击事件。
sessionStorage.setItem('parameter', JSON.stringify(parameter));
var link = angular.element('<a href="' + url + '" rel="noopener" target="' + target + '"></a>');
angular.element(document.body).append(link);
link[0].click();
link.remove();
然后在B页面中获取保存在sessionStorage中的数据并进行处理。
var key = 'parameter';
var parameter = sessionStorage.getItem(key);
if (parameter) {
parameterObj = JSON.parse(para);
......
sessionStorage.removeItem(key);
}
但是将chrome浏览器更新到89.0.4389.90 之后,发现A页面保存的数据在B页面中无法获取到。
查看chrome的更新说明,发现其针对sessionStorage进行了更新.
Stop cloning sessionStorage for windows opened with noopener
When a window is opened with noopener,
Chrome will no longer clone the sessionStorage of its opener;
it will instead start an empty sessionStorage namespace.
This brings Chrome in conformance with the HTML specification.
通过Chrome Plateform Status我们可以看到全平台的89版本的Chrome默认开启了这个功能,也可以看到其他几个主流的浏览器对这个功能的支持情况。
https://www.chromestatus.com/feature/5679997870145536
When a window is opened with noopener, Chrome should not clone the sessionStorage of its opener; it should instead start from an empty sessionStorage namespace.
Motivation
This is a bugfix to match the HTML specification, which added this behavior in 2017: https://github.com/whatwg/html/pull/2832
Status in Chromium
Blink components: Blink>Storage
Enabled by default (tracking bug) in:
Chrome for desktop release 89
Chrome for Android release 89
Android WebView release 89
Consensus & Standardization
After a feature ships in Chrome, the values listed here are not guaranteed to be up to date.
Firefox:Shipped/Shipping
Edge:Positive
Safari:No signal
Web Developers:No signals
二、sessionStorage的规范
- 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
- 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这点和 session cookies 的运行方式不同。
- 打开多个相同的URL的Tabs页面,会创建各自的sessionStorage。
- 关闭对应浏览器窗口(Window)/ tab,会清除对应的sessionStorage。
三、解决方案
通过以上分析我们可以知道,新版本的Chrome浏览器不会再复制sessionStorage给通过noopener方式打开的新页面,导致无法在新的标签页里边访问到共享的数据,由于打开的是我们同一个站点的页面,可以直接将超链接的rel的值改为opener即可。
sessionStorage.setItem('parameter', JSON.stringify(parameter));
var link = angular.element('<a href="' + url + '" rel="opener" target="' + target + '"></a>');
angular.element(document.body).append(link);
link[0].click();
link.remove();