SharedObject类创建的本地共享对象(LSO:local shared object)类似于浏览器cookie,所以也被称作Flash Cookie。类似只是在作用上类似,都是用于将数据保存于客户端,可进行读写。
不同之处似乎更多:
- 浏览器cookie具有过期时间,而Flash Cookie默认永不过期,尽管可以间接地实现expires
- 浏览器cookie文件大小不能超过4k,且同一域最多只能保存20个cookie,而Flash Cookie默认大小为100k,如若不够还可以向用户请求获取更多空间存储Flash Cookie
- 浏览器cookie保存的数据都以字符串形式保存,而Flash Cookie可保存除了AS中可视对象和SharedObject对象本身的任何数据类型
- 浏览器cookie无法跨浏览器进行读写,而Flash Cookie却是跨浏览器的,任何浏览器访问的Flash Cookie都可以是同一个.sol文件
- 浏览器cookie最初为服务器端编程而设计,而且作为HTTP协议的扩展可以自动地在web浏览器与服务器之间传递,而Flash Cookie默认不会在浏览器与服务器之间进行传递
- 浏览器cookie默认域为创建cookie页面所在域,而Flash Cookie默认域为创建Flash Cookie的swf文件所在域,未必是当前页面所在域
静态getLocal()方法是LSO创建和打开以进行读取的机制。getLocal()方法会返回 ShareObject实例,用以取代new运算符以实例化新LSO实例。调用getLocal()方法时至少需要为其传入一个参数,即是LSO的名称; 第二个参数是为LSO指定存储路径便于其他swf共享该LSO数据,默认保存路径为创建LSO的swf文件所在唯一域、路径和文件名组成;第三个参数用以 确定对此共享对象的访问是否只限于通过HTTPS连接传递的swf文件,默认false。如:var user:SharedObject = SharedObject.getLocal(‘user’,'/’);
LSO通过其一个特殊的内建属性data来存储所有数据,如:user.data.name = ‘xxxx’;
在Flash Player卸载时、SharedObject实例被当成垃圾回收时、当调用SharedObject.clear()方法时,LSO数据都会自动保存至 本地磁盘。但是这些方法都不值得信赖,推荐的方式是使用SharedObject.flush()方法来对LSO数据进行存储。flush()方法有一个 可选参数,指定写入数据时应该使用的最小磁盘空间量,默认值为0,表示只使用所需的最小空间。
调用flush()方法返回以下三种结果:
- Error 用户拒绝保存该域的LSO数据,或者Flash Player由于某种原因不能保存数据都会抛出Error
- SharedObjectFlushStatus.FLUSHED 数据成功保存
- SharedObjectFlushStatus.PENDING 没有分配足够的磁盘空间来保存LSO数据。
LSO数据的读取与写入一样简单,只需将共享对象的data属性内的对应属性读取出来即可,如:var name:String = user.data.name;
而删除LSO对象中的数据则需要使用delete运算符,如:delete user.data.name;如需要删除整个LSO对象,调用clear()方法即可:user.clear();
以下代码定义了三个函数setCookie、getCookie、delCookie用以创建/修改、获取、删除LSO数据:
//LSO/FlashCookie wondger@gmail.com import flash.events.NetStatusEvent;function
setCookie(lsoname:String,cname:String,cvalue:*,path:String=null
):Boolean{var
lso:SharedObject = (path!=null&&path.length
) ? SharedObject.getLocal(lsoname,path
) : SharedObject.getLocal(lsoname
); lso.data[cname] = cvalue;try
{var
flushResult:String = lso.flush();if
(flushResult == SharedObjectFlushStatus.FLUSHED
)return
true;//数据保存成功
else
if
(flushResult == SharedObjectFlushStatus.PENDING
) lso.addEventListener(NetStatusEvent.NET_STATUS,onStatus
);//空间不够时
}catch
(e:Error
){ Security.showSettings(SecurityPanel.LOCAL_STORAGE
);//用户禁止保存数据,打开Player的“settings”对话框
}function
onStatus(evt:NetStatusEvent
):Boolean{ lso.removeEventListener(NetStatusEvent.NET_STATUS,onStatus
);if
(evt.info.code ==
)'SharedObject.Flush.Success'
return
setCookie(lsoname,cname,cvalue
);//用户同意允许请求更多的空间
return
false; }return
false; }function
getCookie(lsoname:String,cname:String,path:String=null
):*{var
lso:SharedObject = (path!=null&&path.length
) ? SharedObject.getLocal(lsoname,path
) : SharedObject.getLocal(lsoname
);return
lso.data[cname]; }function
delCookie(lsoname:String,cname:String=null,path:String=null
):Boolean{var
lso:SharedObject = (path!=null&&path.length
) ? SharedObject.getLocal(lsoname,path
) : SharedObject.getLocal(lsoname
);if
(lso
){if
(cname && cname != null
){ delete lso.data[cname]; lso.flush(); }else
lso.clear();return
true; }return
false; }
当然还可以使用JavaScript进行一定的封装方便跨浏览器操作(对检测flash加载完成addCallback注册函数可用一直纠结了很久,没有找到太满意的方法,现在这个将就用):demo
———————————————
update 2011/7/27
补充下,上面提到的间接地实现expires
文章写了很久也忘记了,我想可以这样,每次写cookie的时候,将expires作为一个数据字段保存,即user.data.expires = ****,每次读取cookie的时候,都将此expires读取出来与当前时间比较即可。