如何使用Flash来实现本地存储

我在5月份的一篇文章里列举了一些本地存储解决方案, 包括常见的Cookie、UserData和不是那么常见的globalStorage、Database Storage。文章最后提到了另外两种解决方案:Google Gear和Flash,当时因为觉得用不上就没仔细研究。但实际应用中,那篇文章列出的方案还是不能满足项目的需求。这篇文章就讲一下如何使用Flash来实现本地存储,以及该方案使用的场合。

拿IE6来说,如果要在本地大量存放数据,Cookie因为存放内容太少、浪费用户带宽首先就应该被淘汰掉。UserData在大多数情况下能满足需求,但是它也有一个致命的弱点:只能读取同目录存储,也就是a目录下一个文件不能读取b目录下两一个文件存放的数据。MSDN说明如下:

Security Alert For security reasons, a UserData store is available only in the same directory and with the same protocol used to persist the store. 全文>>

也就是说如果项目中要跨文件夹操作本地存储,UserData也必须被淘汰了。IE不支持Database Storage,IE8才增加了对globalStorage的支持,这个时候Flash就派上用场了。

首先,打开Flash,建立一个工程,编写get、set、remove三个方法并提供给外部程序调用:

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.TimerEvent;
  import flash.net.SharedObject;
  import flash.system.Security;
  import flash.external.ExternalInterface;
  import flash.utils.Timer;

  public class Main extends Sprite {

    Security.allowDomain("*");//修改为自己的域名
    private const storageName:String = "data";

    public function Main() {
      addExternalInterface();
    }

    private function addExternalInterface():void {
      function set(key:String, val:String = ""):void {
        var sobj:SharedObject = SharedObject.getLocal(storageName, "/", false);
        sobj.data[key] = val;
        sobj.flush();
      }

      function get(key:String):String{
        var sobj:SharedObject = SharedObject.getLocal(storageName, "/", false);
        return(sobj.data[key]);
      }

      function remove(key:String):void{
        var sobj:SharedObject = SharedObject.getLocal(storageName, "/", false);
        delete sobj.data[key];
        sobj.flush();
      }

      function isJavaScriptReady():Boolean {
        var isReady:Boolean = ExternalInterface.call("isJSReady");
        return isReady;
      }

      function jsReadyHandler():void {
        trace("javascript js ready"); 
        ExternalInterface.addCallback("set", set);
        ExternalInterface.addCallback("get", get);
        ExternalInterface.addCallback("remove", remove);
        ExternalInterface.call("flashReadyHandler");
      }

      if (ExternalInterface.available) {
        try {
          if (isJavaScriptReady()) {
            jsReadyHandler();
          }else {
            var timerReady:Timer = new Timer(100, 0);
            timerReady.addEventListener(TimerEvent.TIMER, function(evt:TimerEvent):void {
              trace("checking..."); 
              if (isJavaScriptReady()) {
                Timer(evt.target).stop();
                jsReadyHandler();
              }
            });
            timerReady.start();
          }
        }catch (err:SecurityError) {
          trace(err.message);
        }catch (err:Error) {
          trace(err.message);
        }
      }
    }
  }
}

其中,核心功能是依靠SharedObject来实现的。对于这个对象,Adobe官方说明如下:

Shared objects are quite powerful: they offer real-time data sharing between objects that are persistent on the local location. You can think of local shared objects as "cookies."

You can use local shared objects to maintain local persistence. This is the simplest way to use a shared object. For example, you can call SharedObject.getLocal to create a shared object, such as a calculator with memory, in the player. Because the shared object is locally persistent, Flash saves its data attributes on the user's machine when the movie ends. The next time the movie runs, the calculator contains the values it had when the movie ended. Alternatively, if you set the shared object's properties to null before the movie ends, the calculator opens without any prior values the next time the movie runs. 全文>>

补充一下,SharedObject存储在本地的内容是可以跨浏览器读取的,也就是在IE中存储的内容,可以在firefox中读到,这是一个比较有用的特性。另外,SharedObject一般把内容存在下列位置:

Windows XP:C:\Documents and Settings[1]\Application Data\Macromedia\Flash Player#SharedObjects[2][3][4].sol

Windows Vista:C:\Users[1]\AppData\Roaming\Macromedia\Flash Player#SharedObjects[2][3][4].sol ([1]:系统当前用户,[2]:随机字符目录,[3]:网站域名,[4]:SharedObject对象名)

然后用把编译得到的swf文件加到页面中,利用js来调用flash中对应的三个方法就OK了,具体方法都写在演示文件里,就懒得贴出来了。演示地址在这里。(请用IE浏览器打开

update:更新了demo,支持所有的浏览器。

本文链接:参与评论 »

--EOF--

提醒:本文最后更新于 3006 天前,文中所描述的信息可能已发生改变,请谨慎使用。

Comments