全局数据/对象的 Javascript 存储/状态
Posted
技术标签:
【中文标题】全局数据/对象的 Javascript 存储/状态【英文标题】:Javascript storing/state of global data/object 【发布时间】:2012-03-27 23:12:45 【问题描述】:有没有办法将全局数据存储在window
对象中,这样数据可以在页面重新加载/刷新后继续存在。所以假设我分配了我的全局数据/对象-
window.myObject = myProductObject
并且用户刷新/重新加载页面或者可能跳转到我网站的另一个页面。页面重新加载后window.myObject
是否仍然可用?
注意 -:我不能将对象存储在 cookie 中,因为它是一个对象,我的意思是它可能是对另一个自定义对象的引用,或者它可能引用另一个具有通过“window.open”打开
【问题讨论】:
如果您的对象需要是字符串,则将其字符串化:developer.mozilla.org/En/Using_native_JSON 客户端存储唯一真正的解决方案是 indexedDB 【参考方案1】:使用window.top.name
hack
var data = window.top.name ? JSON.parse(window.top.name) :
...
window.top.name = JSON.stringify(data)
window.top.name
在页面加载时持续存在
我建议您改用 lawnchair 之类的抽象
【讨论】:
TIL -window.top.name
和草坪椅。希望我能 +2【参考方案2】:
您可以将对象保存在 cookie 中。但是 localStorage 更好。类似于 cookie,但您可以使用 5Mb。
如果您保存对象而不是字符串,则必须进行 JSON 编码/解码,但使用 localStorage 或 cookie 上的包装器很容易。
这是一个非常简单的 localStorage 包装器(您可以使用 5Mb):
var Storage =
set: function(key, value)
localStorage[key] = JSON.stringify(value);
,
get: function(key)
return localStorage[key] ? JSON.parse(localStorage[key]) : null;
;
你可以这样使用它:
$(function()
var defaultValue = param1: 'value',counter: 0 ,
myObj = Storage.get('myObj') || defaultValue; // get the obj from storage or create it with default values
$('body').html('counter: ' + myObj.counter);
myObj.counter+=1; // increment counter
Storage.set('myObj', myObj); // save it to localStorage
);
你可以在这个 jsFiddle 上试试:http://jsfiddle.net/guumaster/LytzA/3/
【讨论】:
你也可以阅读这个Web Storage explained on Dev.Opera【参考方案3】:您可以尝试将对象的字符串表示形式存储在 cookie 中,前提是该对象仅由值组成(无方法),例如
var foo = a: "a", b: "b" ;
document.cookie = "foo=" + JSON.stringify(foo);
这里有一个很好的 cookie 读取器/写入器示例 - https://developer.mozilla.org/en/DOM/document.cookie
【讨论】:
Cookie 是 错误 解决方案 @Raynos 需要详细说明吗?它可能不是最新的解决方案(本地存储很酷,但我老了,并没有立即想到它)但是 cookie 是解决这个问题的方法 Cookie 随每个 HTTP 请求一起发送,增加了带宽和延迟。无论如何,如果您需要服务器和客户端上的数据,这是一个正确的解决方案,如果您只需要它在客户端上,那么这是一个糟糕的解决方案 @Raynos 请记住仍然不支持本地存储的 large number of browsers(包括 IE7)。根据 OP 的要求,它甚至可能不是一个选项 有比 IE7 支持的 cookie 更好的 hack,window.top.name
和 userData
浮现在脑海。也不要通过网络发送您存储的 cookie。【参考方案4】:
我不确定这个展会是如何跨浏览器的。我至少让它在 chrome、firefox 和 IE9 和 IE8/7 的兼容模式下工作,但你会收到关于弹出窗口的警告。您可以检测弹出窗口是否被阻止并拒绝加载任何内容,直到它们为您的站点启用。见Detect blocked popup in Chrome
我正在使用jQuery绑定到 beforeunload 事件,你可以使用你喜欢的解决方案。
jQuery(function ($)
$(window).bind('beforeunload', function ()
window.open("", "_savedata", "titlebar=0,width=100,height=100").saveData = window.saveData;
);
var store = window.open("", "_savedata");
window.saveData = store.saveData;
store.close();
);
示例:(刷新页面几次)
http://jsfiddle.net/hZVss/1/
按照@Raynos 的要求 - 持续关闭状态 - 你无法序列化的东西(至少在 firefox 和 chrome 中工作,IE 称之为安全问题,但可能与 jsfiddle 使用帧的方式有关)
http://jsfiddle.net/ght9f/2/
免责声明:我不保证这个解决方案的优雅。我只是对使用弹出窗口保持对象状态感到好奇。将您的对象序列化为 JSON 并将其存储在客户端存储中要好得多(@Raynos 会推荐草坪椅 https://github.com/brianleroux/lawnchair/)。如果可以,您应该避免使用 cookie,因为这些数据会被发送回服务器,这可能并不理想。
如果您的主要目标是保留对弹出窗口的引用,您实际上可以通过为弹出窗口命名来做到这一点。这正是我坚持对刷新时创建的弹出窗口的引用的方式。
【讨论】:
使用弹出窗口保持状态是巨魔 同意。不过,无需用不太有用的术语重申。 一个答案是一个推荐的解决方案,而不是一个关于如何解决它的学术问题。 如果您阅读了这个问题,您可能会注意到这个答案实际上回答了这个问题。这也是真正持久化状态的唯一方法,因为 JSON 没有封装整个状态,正如 OP 所提到的。理想的解决方案是以不同的方式进行,但要解决 OP 要求的给定约束的问题,这是唯一的方法。 如果您需要保留不可序列化的状态,或者出于任何原因决定您想要,正如 OP 所要求的那样,这是唯一的方法。我希望 OP 能从解决方案的丑陋中看出,考虑不同的方法是一个更好的主意,但我不会做出这个决定。以上是关于全局数据/对象的 Javascript 存储/状态的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中,将获取的 Firebase 数据存储在本地还是全局状态?