flex调用WMS远程图片所产生安全错误

前言:昨天在Infoq上看到一则消息,说乔布斯不采用flash而转而支持html5是因为flash的安全性等相关问题,想想,其实也还是有部分道理的,因为这两天要碰上了flex的安全问题,觉得这方面真的应该好好改进。

 

描述问题:

地图通过webservice的方式调用规划局GIS共享服务器提供的基础地形图并进行本地显示,其图片是用地图的预生成,即将指定范围的地图按照指定尺寸(如256,512等)和指定格式(如JPEG,PNG等)切成若干行及列的正方形图片,客户端采用flex加载服务的方式进行显示。

加载远程图片代码如下:

var   newUrl:String = serviceUrl + "?" + reqPara ;

newUrl = encodeURI(newUrl);

tempImage.load(newUrl);

之前图片显示一直正常,但问题很快就来了,因为有新的需求,要在地图上标识某个事件发生的位置,并且将图片保存,当然就想到了如下的代码:

var bitmapData : BitmapData = new BitmapData(target.width, target.height);  

bitmapData.draw(target);   

var jpg:JPEGEncoder = new JPEGEncoder();  

jpgByteArray = jpg.encode(bitmapData)

而运行代码则会报出安全错误

获取位置图片流错误122:Error #2122: 安全沙箱冲突:BitmapData.draw:http://192.168.3.247:8085/swf/MainMapClient.swf 不能访问 http://pic.yupoo.com/paranimage/137587f7a2dd/6ztzeftu.jpg。需要一个策略文件,但在加载此媒体时未设置 checkPolicyFile 标志。

 

分析问题:

通常我们在flex中,当你需要获取当前屏幕的信息的时候,通常都会采用bitmapData.draw这个方法(同时,也可以采用ImageSnapshot.captureBitmapData(target)

),这个就类似于快照的意思,但是在使用这个方法的时候,有个非常明显的限制,就是在其文档里面也作如下说明:

其source 对象及(就 Sprite 或 MovieClip 对象来说)其所有子对象必须来自与调用方相同的域,或者必须位于调用方可通过调用 Security.allowDomain() 方法访问的 SWF 文件中。如果不满足这些条件,draw() 方法将不会绘制任何内容。

因为,问题也就是产生在这里,调用的WMS属于远程调用图片,并不属于安全域范围内的图片,所以也就会报错。从另一个通俗的语言来理解,通常flex加载图片时,flex只允许对图片可以只读操作,由于image.content实际上是一个bitmap的实例,而当我们去获取bitmap时,flex便认为这是一个写的操作,因此,会报出安全错误。

 

解决方法:

1,在图片服务器上加crossdomain文件,允许你可以去访问;
  2,写一个server文件(php或者jsp)中转,因为WMS访问的图片是在共享服务器上的,不可能添加crossdomain文件吧,所以只有采用2了,由于后台采用的是spring的后台,因此我直接将请求发送给后台,作用主要就是中转,先是把图片读过来,转化成图片流,并发送至客户端,这样的话,客户端代码就基本上不用修改,当然,具体实现方式还有很多,但基本上原理是一致的。

posted @ 2010-05-17 17:51  GIS小能  阅读(1547)  评论(0编辑  收藏  举报