【问题标题】:Flex: recover from a corrupt local SharedObjectFlex:从损坏的本地 SharedObject 中恢复
【发布时间】:2012-04-13 03:52:04
【问题描述】:

我的 Flex 应用程序使用本地 SharedObjects。已经发生过 Flash cookie 损坏的事件,例如,由于插件崩溃。在这种情况下 SharedObjects.getLocal 会抛出异常 (#2006)。

我的客户希望应用程序能够正常恢复:如果 cookie 损坏,我应该将其替换为空的。

问题是,如果 SharedObject.getLocal 不返回 SharedObject 的实例,我就没有什么可以调用 clear() 了。

如何删除或替换此类 cookie?

非常感谢!

编辑:

没有太多代码可以显示——我访问本地 cookie,我可以轻松捕获异常。但是,一旦我发现异常,如何在同一位置创建一个新的共享对象?

 try {
     localStorage = SharedObject.getLocal("heywoodsApp");
 } catch (err:Error) {
       // what do I do here?
 }

使用编辑器破坏 Flash cookie 的二进制内容很容易重现该错误。

【问题讨论】:

  • +1 表示问题;但我不知道解决方案是什么。你的应用程序在做什么插件崩溃是司空见惯的?可以分享代码吗?你能分享完整的例外吗?我想知道您是否可以使用 uncaughtException 事件来创建一个全新的 SharedObject?
  • 该应用程序是监控和分析公司内部使用的业务数据的前端。崩溃并不常见,但有报告称 Windows 崩溃后 cookie 损坏,并且由于用户在技术上不够熟练,无法清理他们的 Flash cookie,因此客户端已提出功能请求(即我如果我这样做,可以获得更多的钱)如果事件再次发生,该应用程序会为他们做这件事。我将代码放在原始评论中。
  • @ThomasHeywood 您是否以某种方式解决了这个问题?我在这里没有看到任何好的答案:/
  • 不,我们让它滑动并记录问题。

标签: apache-flex recovery corrupt shared-objects


【解决方案1】:

您需要测试 SharedObject 的长度,如果它为 0,则重新创建。另外,始终使用 flush 来写入对象。这是我们用来计算软件启动次数的函数:

private function usageNumber():void {
    usage = SharedObject.getLocal("usage");

    if (usage.size > 0) {
       var usageStr:String = usage.data.usage;      
       var usageNum:Number = parseInt(usageStr);

       usageNum = usageNum + 1; 
       usageStr = usageNum.toString();

       usage.data.usage = usageStr;
       usage.flush();

       countService.send();

    } else {

       usage.data.usage = "1";
       usage.flush();

       countService.send();
    }

}

请务必注意,如果对象不可用,它将自动重新创建。这就是 SharedObjects 令人困惑的部分。

我们所做的只是全局声明变量:

public var usage:SharedObject;

然后在init()函数中调用它:

usage = SharedObject.getLocal("usage");

如果它不存在,那么它就会被创建。

【讨论】:

  • 感谢伟大的代码 sn-p。不幸的是,它不能解决我的问题。我从来没有得到 SharedObject 的实例(代表它的变量被赋值为 null),所以没有什么可以调用 length()(或 flush() 等)。
  • 好的,所以您在访问共享对象时遇到异常?
  • 是的。我调用 SharedObject.getLocal("myStorage"),它会引发 RangeError,这是 getLocal 找到 Flash cookie 但无法检索它时的预期行为。所以我没有使用 SharedObject 的实例。
  • 用我们的初始化方式更新了我的答案。我发现没有任何东西表明会发生范围错误。另外,我应该指出,当我测试时,我会使用 clear() 来确保对象是新鲜的。
  • @ThomasHeywood 为什么不检查是否为空,如果为空则重新创建?这对你不起作用吗?显然,你会检查的,但我不得不问。
【解决方案2】:

我不确定您为什么会收到范围错误 - 特别是如果您报告可以找到它。对于这样的事情,我唯一的猜测是跨域策略有可能跨越边界。假设 IT 可以控制服务器的托管位置,如果子域曾经更改甚至访问类型(从标准到 https),这可能会导致问题,尤其是在应用程序正在进行时(已经通过多个版本)。我很难相信您正在尝试检索已由另一个应用程序命名的命名 SO - 本质上是名称冲突。在这方面,即使在这些事情上,我们中的许多人仍然使用 reverse-dns 风格的命名约定。

如果你能捕捉到错误,那么恢复起来应该是相对简单的: - 只需在 try 范围之外声明变量,这样它也可以被捕捉到。 [编辑]:由于它是一个静态方法,您可能需要创建一个后缀,以便从本质上使用一个新标识符重新开始。

var mySO:SharedObject;
....
catch(e:Error)
{
      mySO = SharedObject.getLocal('my.reversedns.so_name_temp_name');
      //might want to dispatch an error event or rethrow a specific exception
      //to alert the user their "preferences" were reset.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多