全局数据/对象的 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.nameuserData 浮现在脑海。也不要通过网络发送您存储的 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 存储/状态的主要内容,如果未能解决你的问题,请参考以下文章

Vuex和单纯的全局对象有啥区别

在 React 中,将获取的 Firebase 数据存储在本地还是全局状态?

application详解

如何从 Kafka 全局状态存储中删除记录?

Javascript - 在对象中存储函数 - 不好的做法? [关闭]

每日灵魂一问-node.js的全局对象有哪些?