[AS3] 解决BitmapData.draw()安全沙箱问题!

http://bbs.9ria.com/thread-41362-1-1.html

在程序中加载外部图片是很正常的事情,比如我做一个校内应用,需要调用用户头像,而校内有没有给我设置crossdomain.xml,这时我又有让用户提交程序错误的截图,怎么办?
  想到使用BitmapData.draw()这个方法是是个很自然的反应,因为它可以对任何显示对象进行拍照,但是它会有安全问题的隐患,因为我加载了存储在校内服务器上的用户头像,而没有得到校内的站点配置允许,那我再对程序界面拍照时就会报安全错误,拍出来的截图为一片空白。虽然我们不能直接对加载进来的图片进行相应的操作,但是我们可以使用Loader代理添加到我们的应用程序中,比如:
  1.   var loader:Loader = new Loader();
  2.    var path:URLRequest = new URLRequest("photoPath");
  3.    loader.load(path);
  4.    photoContainer.addChild(loader);
复制代码
在这里我们添加Loader对象到显示列表,而不是在侦听完成事件时把loader.content添加到显示列表,这样可以避免安全错误,又可以把图片添加到显示列表中,并呈现给用户。

然后,使用如下两个方法来配合BitmapData.draw()来进行程序拍照。
  1. /**
  2. * 移除Loaders
  3. * @param   container
  4. * @param   list
  5. */
  6. private function removeLoaders(container:DisplayObjectContainer,loaderList:Array):void
  7. {
  8.    for (var i:int = 0; i < container.numChildren; i++)
  9.    {
  10.       var child:DisplayObject = container.getChildAt(i);        
  11.       if (child is Loader)
  12.       {
  13.          var point:Point = new Point(child.x, child.y);
  14.          loaderList.push([child, child.parent, point]);               
  15.          continue;
  16.       }
  17.       
  18.       if(child is DisplayObjectContainer)
  19.          removeLoaders(child as DisplayObjectContainer, loaderList);
  20.    }
  21. }

  22. /**
  23. * 添加Loaders
  24. * @param   loaderList
  25. */
  26. private function addLoaders(loaderList:Array):void
  27. {
  28.    var list:Array = null;
  29.    var point:Point = null;
  30.    var loader:Loader = null;
  31.    var loaderParent:DisplayObjectContainer = null;
  32.    for (var i:int = 0; i < loaderList.length; i++)
  33.    {
  34.       list = loaderList[i];
  35.       loader = list[0];
  36.       loaderParent = list[1];
  37.       point = list[2];
  38.       loader.x = point.x;
  39.       loader.y = point.y;
  40.       loaderParent.addChild(loader);
  41.    }
  42. }
复制代码
在拍照前,使用removeLoaders方法,并把被移除的图片Loader存储到loaderList数组里面。移除后,就可以安全地进行拍照了!在拍照完成后,再调用addLoaders把刚才移除的图片添加回来,这样就解决了安全沙箱问题!

removeLoaders移除的是所有通过Loader加载进来的图片,因为它是一个递归函数,可以遍历显示列表里面的所有显示对象。很显然loaderList存储的也是所有的图片,这样就可以既能发送用户反馈,又能避免程序错误。

唯一的一点瑕疵就是:拍出来的照片是没有用户头像的,这并不影响我们根据用户提交的图片来分析程序错误,所以这点瑕疵不足以成为我们拒绝使用它的理由,——自恋一下,

你可能感兴趣的:(actonscript)