Angularjs 为什么在不同的浏览器实例之间使用会话存储?
背景Angularjs 为什么在不同的浏览器实例之间使用会话存储?,angularjs,google-chrome,typescript,persistence,session-cookies,Angularjs,Google Chrome,Typescript,Persistence,Session Cookies,背景 在我正在开发的一个应用程序中,我发现我可以在Windows 10上的Chrome 62中定义sessionStorage中的值,显然在一个选项卡中更改该值会影响指向同一键的其他选项卡 我的工作假设是localStorage应该在所有浏览器窗口中保存信息,而sessionStorage应该只保存特定窗口或选项卡的信息 更具体地说,我使用AngularJS服务作为会话存储交互层: export class PersistenceSvc { public static $inject:
在我正在开发的一个应用程序中,我发现我可以在Windows 10上的Chrome 62中定义
sessionStorage
中的值,显然在一个选项卡中更改该值会影响指向同一键的其他选项卡
我的工作假设是localStorage
应该在所有浏览器窗口中保存信息,而sessionStorage
应该只保存特定窗口或选项卡的信息
更具体地说,我使用AngularJS服务作为会话存储
交互层:
export class PersistenceSvc {
public static $inject: string[] = ['$window'];
public constructor(public $window: ng.IWindowService) {}
public save<T>(name: string, data: T): void {
const saveData: string = JSON.stringify(data);
this.$window.sessionStorage.setItem(name, saveData);
}
public load<T>(name: string): T {
const loadData: string = this.$window.sessionStorage.getItem(name);
const result: T = JSON.parse(loadData) as T;
return result;
}
}
当只使用一个选项卡进行操作时,这很好(除非从iOS设备上运行,但这与我遇到的情况无关。)当您执行以下操作时,您会看到一些更有趣的行为
步骤:1.打开一个Chrome实例。创建一个新选项卡,并将其拖出,使其成为自己的窗口。
2.导航到使用上述代码的站点。
3.在您的站点上执行导致
someSvc
的数据状态在第一个浏览器中具有不同数据的操作。4.在您的站点上执行导致
someSvc
的数据状态在第二个浏览器中具有不同数据的操作。5.在你的网站上做一些事情,利用第一个浏览器中的
someSvc
数据状态。6.请注意,第一个浏览器实例上使用的数据是由第二个浏览器实例提供的。(这就是问题所在,就在这里。) 问题:
在过去,我没有做过很多cookie/localStorage/sessionStorage编程,所以很可能我对某些东西产生了严重的误解。记住这一点,为什么
window.sessionStorage
的行为方式和它不应该的行为方式一样
编辑:结果是有问题,但不是客户端的问题。结束这个问题,因为我是在假设客户机是问题所在的情况下操作的。您的代码有问题,因为在浏览器控制台上进行快速简单的测试表明会话存储只影响打开的浏览器选项卡。右选项卡中的更改不会反映到左选项卡:
查看我的代码后,确实存在问题,但不是客户端问题,而是服务器端问题。您认为
会话存储
工作正常,这是正确的。我要结束这个问题,因为我是在错误的假设下操作的。我转录的persistenceSvc.load
函数中也有一个输入错误:我没有返回result
。这在原来的帖子里也被修正了。
export function persistSomeData(
someSvc: Services.SomeService,
userAgentSvc: Services.UserAgentSvc,
persistenceSvc: Services.PersistenceSvc,
$window: ng.IWindowService) {
if(userAgentSvc.isMobileSafari()) {
// Special instructions for iOS devices.
return;
}
const dataToPersist: Models.DataModel = persistenceSvc.load<Models.DataModel>('SomeData');
if(dataToPersist) {
// Set up the state of someSvc with the data loaded.
} else {
// Phone home to the server to get the data needed.
}
$window.onbeforeunload = () => {
persistenceSvc.save<Models.DataModel>('SomeData', someSvc.dataState);
};
}
persistSomeData.$inject = [
// All requisite module names, omitted from example because lazy.
];
angular
.module('app')
.run(persistSomeData);