【问题标题】:Javascript storing/state of global data/object全局数据/对象的 Javascript 存储/状态
【发布时间】:2012-03-27 23:12:45
【问题描述】:

有没有办法将全局数据存储在window 对象中,这样数据可以在页面重新加载/刷新后继续存在。所以假设我分配了我的全局数据/对象-

window.myObject = myProductObject

并且用户刷新/重新加载页面或者可能跳转到我网站的另一个页面。页面重新加载后window.myObject 是否仍然可用?

注意 -:我不能将对象存储在 cookie 中,因为它是一个对象,我的意思是它可能是对另一个自定义对象的引用,或者它可能引用另一个具有通过“window.open”打开

【问题讨论】:

标签: javascript dom cross-browser browser


【解决方案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/

【讨论】:

【解决方案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 能从解决方案的丑陋中看出,考虑不同的方法是一个更好的主意,但我不会做出这个决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 2014-02-24
  • 2012-09-03
  • 2017-07-04
  • 1970-01-01
相关资源
最近更新 更多