flash as3 socket安全服务网关(socket policy file server)

关键字:

SecurityErrorEvent socket as3

flash有着自己的一套安全处理模式,在socket方面,我这样的菜鸟无法理解他的好处:一句话,不怀好意的人如果想用flash写一段带破坏意义的socket客户端(我这里只谈客户端,不谈as3 做 socketserver)程序,你给禁止了,他可以用其他的程序,实际上,这种人也不会用flash去写;你的这些安全的东东实际给真正的使用者带来很多的麻烦。

抱怨的话只能说说,我们无法改变,说说解决方案,

网上一般有以下关于SecurityErrorEvent处理的方式:

1 Security.allowDomain("*");

2 Security.loadPolicyFile("http://oa.oa.com/crossdomain.xml");

3 <policy-file-request/> <cross-domain-policy><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>

4 <param value="all" name="allowNetworking">

第3种是socket服务器用到的,

-------------------------------------------------------

我遇到的问题是——我要做文件上传进度,网上流行的方法是用FileReference的upload,我不想用,因为我有用URLRequest+loader的上传代码。

我的代码是正常向apache+php的服务器发送正常的post表单,代码也完全没有特殊的地方,但是URLRequest不能表现上传的进度,只能表示下载的进度,所以,我想用socket去实现,写好代码之后,出问题了,安全问题,我先试了上面的1 2 4,结果都不行,因为是apache做的服务器端,第三种派不上用场。

看了这篇文章:

http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html

我了解到flash可以有一个统一的”socket安全配置服务器“,端口是843,于是我写了一个安全配置服务器,php的,代码如下:

<?php
define('policy_request', "<policy-file-request/>");
define('policy_response', '<cross-domain-policy><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>');
define('policy_response_len', strlen(policy_response)+1); 
define('EC', chr(10));

$host="0.0.0.0";
$port=843;

$socket=socket_create(AF_INET,SOCK_STREAM,0);
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
    echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
}

socket_bind($socket,$host,$port);
$rett=socket_listen($socket,3);
//socket_set_nonblock($socket);
$clients = array($socket);

while(1){
	$read = $clients;
	$writes=NULL;$execs=NULL;
	if(socket_select($read, $writes, $execs, 2) < 1){
		continue;
	}
	
	if(in_array($socket,$read)) {
		$clients[] = $newsock = socket_accept($socket);
		socket_set_nonblock($newsock);
		$key = array_search($socket,$read);
		unset($read[$key]);
	}

	foreach($read as $read_sock) {
		$data = trim(socket_read($read_sock, 512, PHP_BINARY_READ));
		
		if($data == false) {
			$key = array_search($read_sock, $clients);
			unset($clients[$key]);
			socket_close($read_sock);
			continue;
		}
		
		if($data==policy_request){
			socket_write($read_sock,policy_response, policy_response_len);
		}else socket_write($read_sock,"Bye".EC);

		socket_close($read_sock);
		$key = array_search($read_sock, $clients);
		unset($clients[$key]);
	}
}

socket_close($socket);
当然还遇到其它曲折,就是如何把ByteArray分段发送,见我的上一篇文章。

贴上完整的as代码

package 
{

	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.ExternalInterface;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.FileReferenceList;
	import flash.net.Socket;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLVariables;
	import flash.system.Security;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	import flash.utils.setTimeout;
	import flash.events.OutputProgressEvent;

	public class ASUploader extends Sprite
	{
		public var btnTxtField:TextField = new TextField();

		public var fileMulti:FileReferenceList;
		public var fileOne:FileReference;
		public var setParamList:Array;

		public var request:URLRequest;
		public var boundary:String = "---BbC04y";// 数据分界符
		public var httpSeparator:String = "
";
		public var fileQueue:Object = {};
		public var queueCounts:int = 0;

		// Values passed in from the HTML
		private var movieName:String;
		private var uploadUrl:String;
		private var lableText:String;
		private var textTopPadding:uint;
		private var textLeftPadding:uint;
		private var filePostName:String;
		private var postParams:Object;
		private var fileTypes:String;
		private var fileTypesDesc:String;
		private var fileTotalSize:int = 0;
		private var fileSizeLimit:int = 0;
		private var fileUploadLimit:int = 0;
		private var fileQueueLimit:int = 0;
		private var multiFiles:Boolean = true;
		private var requeueOnError:Boolean = false;
		private var httpSuccess:Array = [];
		//private var debugEnabled:Boolean;

		private var uploadCompleteHandler:String;
		private var uploadProgressHandler:String;
		private var fileSelectCompleteHandler:String;
		private var fileSelectStartHandler:String;
		
		private var buttonImage:String;

		public function ASUploader()
		{
			
			// 初始化参数
			this.movieName = root.loaderInfo.parameters.movieName;
			this.uploadUrl = root.loaderInfo.parameters.uploadUrl;
			this.lableText = root.loaderInfo.parameters.lableText;
			this.textTopPadding = uint(parseInt(root.loaderInfo.parameters.textTopPadding));
			this.textLeftPadding = uint(parseInt(root.loaderInfo.parameters.textLeftPadding));
			this.filePostName = root.loaderInfo.parameters.filePostName;
			this.fileTypes = root.loaderInfo.parameters.fileTypes;
			this.fileTypesDesc = root.loaderInfo.parameters.fileTypesDesc + " (" + this.fileTypes + ")";
			this.postParams = {"_PostFromASUploader_":"1"};
			this.loadPostParams(root.loaderInfo.parameters.postParams);

			try{
				buttonImage = root.loaderInfo.parameters.buttonImage;
				if(buttonImage==null)	buttonImage = "http://oa.oa.com/images/green/pic.jpg";
			}catch(e){
				buttonImage = "";
			}
			ExternalInterface.call("console.log",'>>> <<<<<< root.loaderInfo.parameters'+root.loaderInfo.parameters.buttonImage);

			if (! this.lableText)
			{
				this.lableText = "Please Select Files";
			}
			if (! this.fileTypes)
			{
				this.fileTypes = "*.*";
			}
			if (! this.fileTypesDesc)
			{
				this.fileTypesDesc = "All Files";
			}

			try
			{
				this.fileUploadLimit = int(root.loaderInfo.parameters.fileUploadLimit);
				if (this.fileUploadLimit < 0)
				{
					this.fileUploadLimit = 0;
				}
			}
			catch (ex:Object)
			{
				this.fileUploadLimit = 0;
			}

			try
			{
				this.fileQueueLimit = int(root.loaderInfo.parameters.fileQueueLimit);
				if (this.fileQueueLimit < 0)
				{
					this.fileQueueLimit = 0;
				}
			}
			catch (ex:Object)
			{
				this.fileQueueLimit = 0;
			}

			try
			{
				this.multiFiles = root.loaderInfo.parameters.multiFiles;
				if (this.multiFiles == "false" || this.multiFiles == "0")
				{
					this.multiFiles = false;
				}
				else
				{
					this.multiFiles = true;
				}
			}
			catch (ex:Object)
			{
				this.multiFiles = false;
			}

			//Callback
			try
			{
				this.uploadCompleteHandler = root.loaderInfo.parameters.uploadCompleteHandler;
			}
			catch (ex:Object)
			{
				this.uploadCompleteHandler = "";
			}
			
			try
			{
				this.fileSelectCompleteHandler = root.loaderInfo.parameters.fileSelectCompleteHandler;
			}
			catch (ex:Object)
			{
				this.fileSelectCompleteHandler = "fileSelected";
			}
			
			try
			{
				this.fileSelectStartHandler = root.loaderInfo.parameters.fileSelectStartHandler;
			}
			catch (ex:Object)
			{
				this.fileSelectStartHandler = "";
			}
			
			try
			{
				this.uploadProgressHandler = root.loaderInfo.parameters.uploadProgressHandler;
			}
			catch (ex:Object)
			{
				this.uploadProgressHandler = "";
			}
			this.debug("this.fileSelectCompleteHandler: " + this.fileSelectCompleteHandler + ", this.uploadCompleteHandler: " + this.uploadCompleteHandler + ", this.uploadProgressHandler="+
					   this.uploadProgressHandler +  ", this.multiFiles=" + this.multiFiles + ', this.fileQueueLimit='+this.fileQueueLimit);
			
			Security.allowDomain("*");
			
			
			this.fileQueue = [];


			this.fileMulti = new FileReferenceList();
			this.fileOne = null;

			this.buttonMode = true;
			this.useHandCursor = true;

			this.stage.align = "TL";
			this.stage.scaleMode = "noScale";
			//this.stage.addEventListener(Event.RESIZE, onResize);

			this.btnTxtField.htmlText = this.lableText;
			var format:TextFormat = new TextFormat("Georgia");
			format.size = 18;
			this.btnTxtField.setTextFormat(format);
			this.btnTxtField.autoSize = "center";
			this.btnTxtField.x = this.textLeftPadding;
			this.btnTxtField.y = this.textTopPadding;
			this.btnTxtField.border = false;
			this.btnTxtField.selectable = false;

			if(buttonImage.length<1){
				addChild(this.btnTxtField);
			}
			else{
				loadImg(buttonImage);
			}
			this.fileMulti.addEventListener(Event.COMPLETE, complete);
			this.fileMulti.addEventListener(Event.OPEN,open);
			this.fileMulti.addEventListener(Event.CANCEL, cancel);
			//点击取消按钮会广播这个事件;
			this.fileMulti.addEventListener(Event.SELECT, select);
			this.fileMulti.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

			//onResize(null);


			// 设置javascript要回调的函数
			ExternalInterface.addCallback("sendPostDataToAs", addPostParams);
			ExternalInterface.addCallback("selectFiles", selectFiles);
			ExternalInterface.addCallback("upload", upload);
			ExternalInterface.addCallback("setParam", setParam);
		}
		private function loadImgCb(obj:DisplayObject){
			try{
				trace(obj);
				obj.x=0;
				obj.y=0;
				obj.addEventListener(MouseEvent.CLICK, selectFiles);
			}catch(e){
				trace(e);
			}
		}
		/**
		 * 打开选择文件对话框
		 */
		public function selectFiles(e:MouseEvent):void
		{
		
			try
			{
				this.queueCounts = 0;


				var allowed_file_types:String = "*.*";
				var allowed_file_types_desc:String = "All Files";

				if (this.fileTypes.length > 0)
				{
					allowed_file_types = this.fileTypes;
				}
				if (this.fileTypesDesc.length > 0)
				{
					allowed_file_types_desc = this.fileTypesDesc;
				}


				if (this.multiFiles)
				{
					this.fileMulti.browse([new FileFilter(allowed_file_types_desc, allowed_file_types)]);
				}
				else
				{
					this.fileOne = new FileReference();
					this.fileOne.addEventListener(Event.SELECT, this.frefSelect);
					this.fileOne.addEventListener(Event.COMPLETE, frefComplete);
					this.fileOne.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					this.fileOne.browse([new FileFilter(allowed_file_types_desc, allowed_file_types)]);
				}
			}
			catch (ex:Error)
			{
				ExternalInterface.call("alert","doSeletFiles error:"+ex.toString());
				this.debug("Exception: " + ex.toString());
			}
			if(this.fileSelectStartHandler)ExternalInterface.call(this.fileSelectStartHandler);
			
		}

		private function frefSelect(e:Event):void
		{
			this.fileOne.load();
		}

		/**
		 * IO失败
		 */
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			this.debug("ioErrorHandler: " + event);
		}

		/**
		 * 设置参数
		 */
		public function addPostParams(params:Object):void
		{
			for (var key:String in params)
			{
				this.postParams[key] = params[key];
			}
		}

		/**
		 * 设置参数,给js调用
		 */
		private function setParam(key:String, value:String)
		{
			this.postParams[key] = value;
		}
		/**
		 * 上传已选文件
		 */
		public function upload():void
		{
			uploadUrl = 'http://oa.*.net/u.php';trace(uploadUrl);
			uploadWidthSocket();
			
			/*this.request = new URLRequest(uploadUrl);
			this.request.method = "POST";
			this.setHeader("Cache-Control", "no-cache");
			this.setHeader("Content-Type", "multipart/form-data;boundary=" + boundary);

			this.request.data = new ByteArray  ;
			this.writeBodyData(this.fileQueue);
			this.writeBodyData(this.postParams);
			this.request.data.writeUTFBytes("--" + boundary + "--");
			this.request.data.writeUTFBytes(httpSeparator);
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = "binary";
			loader.addEventListener(Event.COMPLETE, uploadComplete);
			loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);

			loader.load(request);
*/
		}
		private function parseUrl(url:String) :Object{
			var rtn:Object=new Object();
			var proto:String= "http";
			
			if(url.toLowerCase().indexOf("http://")==0){
				url =url.substring(7);
			}

			trace("parseUrl 1: "+url);
			var host:String="";
			var uri:String="";
			var port:int = 80;
			if(url.indexOf("/")!=-1){
				host = url.substr(0, url.indexOf("/"))
				uri = url.substr(url.indexOf("/"))
			}else{
				host= url;
				uri = "/";
			}

			if(host.indexOf(':')!=-1){
				port =int( host.substr(host.indexOf(':')+1));
				host = host.substr(0, host.indexOf(':')-1);
			}

			return {'proto': proto, 'host':host,'port':port, 'uri': uri};
		}
		var  socket:Socket ;
		var headers:String='';
		public function uploadWidthSocket():void{
			var path:Object = parseUrl(uploadUrl); 
			for(var a:String in path)
				trace(a+"="+path[a]);			
			this.debug("uploadWidthSocket 1:");
			this.request = new URLRequest(uploadUrl);
			this.request.data = new ByteArray  ;
			//this.request.data.writeUTFBytes(headers);
			this.writeBodyData(this.fileQueue);
			this.postParams= {'B':"1",'C':"2"	};
			this.writeBodyData(this.postParams);
			this.request.data.writeUTFBytes("--" + boundary + "--");
			this.request.data.writeUTFBytes(httpSeparator);
			this.request.data.position = 0;
			
			//var _d: ByteArray = new ByteArray;		
			//_d.endian = Endian.BIG_ENDIAN ;			
			//_d.writeBytes(request.data as ByteArray);
			this.debug("uploadWidthSocket 2:");
			headers=
				"POST "+path.uri+"?a=1"+' HTTP/1.1'+httpSeparator
				+ 'Host: '+path.host +httpSeparator
				+ 'Cache-Control: no-cache'+httpSeparator
				+"Content-Type: multipart/form-data;boundary=" + boundary+httpSeparator
				+ 'Content-Length: '+this.request.data.bytesAvailable+httpSeparator
				+"Connection: Close"+httpSeparator+httpSeparator;
			//Security.loadPolicyFile("http://oa.oa.com/crossdomain.xml");
			socket = new Socket();
			socket.endian = flash.utils.Endian.BIG_ENDIAN;
			socket.addEventListener(Event.CLOSE,closeHandler);
			socket.addEventListener(Event.CONNECT,onConnectEvent);
			socket.addEventListener(IOErrorEvent.IO_ERROR,onDataError);		
			socket.addEventListener(ProgressEvent.SOCKET_DATA,onDataEvent);
			socket.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS,progressHandlerSocket);
			socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
			this.debug("uploadWidthSocket 3:");
			this.debug(path.host+ ":"+ path.port);
			
			d = new ByteArray  ;
			d.writeUTFBytes(headers);			
			d.writeBytes(this.request.data as ByteArray);
			d.position = 0;
			total_length = d.length;

			per = int(total_length /100);
			if(per<512) per = 512;
			if(per>20480) per = 20480;
			read_total = 0;
			
			socket.connect(path.host, path.port);//);
			//socket.connect("192.168.0.97", 843);//);
		}

		private function closeHandler(event:Event):void {
			this.debug("closeHandler:"+ event);
		}

		var total_length:int;
		var per:int;
		var d:ByteArray;
		var read_total:int;
		
		private function onConnectEvent(event:Event):void {	
			this.debug(headers);

			this.debug("total_length="+total_length+",per="+per);
			this.debug("uploadWidthSocket 4:");
			sendASection();
		}
		
		var tmp:ByteArray = new ByteArray();		
		private function sendASection():void{
			if(d.bytesAvailable>0){
				try{
					tmp = new ByteArray ();
					tmp.clear();
					tmp.position = 0;
					var read_length = d.bytesAvailable>per?per:d.bytesAvailable;
					
					trace(read_total +","+  read_length);
					
					d.readBytes(tmp,  0, read_length);					
					tmp.position = 0;
					
					read_total+=tmp.length;
					trace(
							   "progressHandler d.position:" + (d.position)+", current sent: "+tmp.bytesAvailable+"-"+ 
							   tmp.length+"/"+read_length+ ", left: "+ d.bytesAvailable + 
							   ", total_length=" + total_length
							   );
					socket.writeBytes(tmp as ByteArray);
					socket.flush();
					
					if (this.uploadProgressHandler)
					{
						//this.uploadProgressHandler
						try{
							ExternalInterface.call(this.uploadProgressHandler, d.position, total_length);
						}catch(e){
							trace(e)
						}
					}
										//if(tmp.length<per) break;
				}catch(e){
					this.debug(e);
					//break;
				}
			}else trace("----------------------DONE ?--------------------------");
		}
		private function onDataEvent(event:ProgressEvent):void {
			var src:String = socket.readUTFBytes(socket.bytesAvailable);
			this.debug("onDataEvent:"+ src);
		}
		
		private function onDataError(Error:IOErrorEvent) {
			this.debug("onDataError:"+ Error);
		}
		
		private function progressHandlerSocket(event:OutputProgressEvent):void {
			//this.debug("progressHandler loaded:" + event.bytesPending + " total: " + event.bytesTotal);
			sendASection()
		}
		
		private function securityErrorHandler(event:SecurityErrorEvent):void {
			this.debug('AAAAA1 安全错误,关闭连接');
		}

		private function progressHandler(event:ProgressEvent):void
		{
			if (this.uploadProgressHandler)
			{
				this.debug("progressHandler loaded 0:" + event.bytesLoaded + " total: " + event.bytesTotal);
				//this.uploadProgressHandler
				ExternalInterface.call(this.uploadProgressHandler, event.bytesLoaded, event.bytesTotal);
			}

			this.debug("progressHandler loaded 1:" + event.bytesLoaded + " total: " + event.bytesTotal);
		}

		/**
		 * 上传完成处理方法
		 */
		public function uploadComplete(event:Event):void
		{
			// JS有上传完成回调函数,则调用
			if (this.uploadCompleteHandler)
			{
				// event.target.data.toString() 服务端返回的字符串
				ExternalInterface.call(this.uploadCompleteHandler, event.target.data.toString());
			}
		}



		public function complete(e:Event):void
		{
		}

		public function open(e:Event):void
		{
		}

		public function cancel(e:Event):void
		{
		}

		public function select(e:Event):void
		{
			this.debug("select 1:");
			for (var i:uint=0; i<this.fileMulti.fileList.length; i++)
			{
				this.fileMulti.fileList[i].addEventListener(Event.COMPLETE, frefComplete);
				this.fileMulti.fileList[i].addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
				this.fileMulti.fileList[i].load();
			}
		}

		public function frefComplete(e:Event):Boolean
		{
			this.debug("select 2:");
			var contentType:String = "unknow";
			if (e.target.type == ".gif")
			{
				contentType = "image/gif";
			}
			else if (e.target.type == ".png")
			{
				contentType = "image/png";
			}
			else if (e.target.type == ".doc")
			{
				contentType = "application/msword";
			}
			else if (e.target.type == ".docx")
			{
				contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
			}
			else if (e.target.type == ".xls")
			{
				contentType = "application/vnd.ms-excel";
			}
			else if (e.target.type == ".xlsx")
			{
				contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
			}
			else if (e.target.type == ".ppt")
			{
				contentType = "application/vnd.ms-powerpoint";
			}
			else if (e.target.type == ".pptx")
			{
				contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
			}
			else if (e.target.type == ".pdf")
			{
				contentType = "application/pdf";
			}
			else if (e.target.type == ".zip")
			{
				contentType = "application/x-zip-compressed";
			}
			else if (e.target.type == ".wav")
			{
				contentType = "audio/wav";
			}
			else if (e.target.type == ".bmp")
			{
				contentType = "image/bmp";
			}
			else if (e.target.type == ".mp3")
			{
				contentType = "audio/mpeg";
			}
			else if (e.target.type == ".jpg")
			{
				contentType = "image/jpeg";
			}
			if (e.target.size == 0)
			{
				return false;
			}
			this.fileTotalSize +=  e.target.size;
			
			if (this.fileSizeLimit > 0 && this.fileTotalSize > this.fileSizeLimit)
			{
				return false;
			}
			
			ExternalInterface.call(this.fileSelectCompleteHandler!=null&&this.fileSelectCompleteHandler.length>0?this.fileSelectCompleteHandler:'fileSelected', e.target.name, e.target.size, this.movieName);
			var mimeType:String = "text/plain";
			var byte1:int = e.target.data.readUnsignedByte();
			var byte2:int = e.target.data.readUnsignedByte();trace("6.4");
			if (e.target.data is ByteArray)
			{
				mimeType = getMimeTypeFromBytes(byte1,byte2);
				this.fileQueue[queueCounts] = {"mimeType":mimeType,"filename":e.target.name,"data":e.target.data};
				this.queueCounts++;
			}
			else
			{//可能上传文本文件
				this.fileQueue[queueCounts] = {"mimeType":mimeType,"filename":e.target.name,"data":e.target.data};
				this.queueCounts++;
			}
			
			if (this.fileQueueLimit > 0 && this.queueCounts > this.fileQueueLimit)
			{
				return false;
			}
			else
			{trace("6.6");
				upload();
				return true;
			}
			
			return true;
		}

		/**
		 * 根据文件头两字节来判断MimeType类型
		 */
		public function getMimeTypeFromBytes(byte1:int, byte2:int):String
		{
			var code:String = byte1 + "" + byte2;
			var mimeType:String = "UnKnow";
			switch (code)
			{
				case "7790" :
					mimeType = 'application/octet-stream';
				case "6787" :
					mimeType = 'application/x-shockwave-flash';
					break;
				case "8075" :
					mimeType = 'application/bmp';
					break;
				case "6677" :
					mimeType = 'image/bmp';
					break;
				case "7173" :
					mimeType = 'image/gif';
					break;
				case "255216" :
					mimeType = 'image/jpeg';
					break;
				case "13780" :
					mimeType = 'image/png';
					break;
				case "79103" :
					mimeType = 'application/ogg';
					break;
			}
			return mimeType;
		}

		public function setHeader(headerName:String, headerValue:String):void
		{
			request.requestHeaders.push(new URLRequestHeader(headerName, headerValue));
		}

		/**
		 * 向发送请求类写入二进制数据
		 * 
		 */
		public function writeBodyData(srcData:Object):void
		{
			var key:String;
			for (key in srcData)
			{
				trace(key+"="+srcData[key]);
				if (srcData[key] is String)
				{
					this.request.data.writeUTFBytes("--" + boundary);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes("Content-Disposition: form-data; name="" + key + """);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes(srcData[key]);
					this.request.data.writeUTFBytes(httpSeparator);
				}
				else if (srcData[key].data is ByteArray)
				{
					this.request.data.writeUTFBytes("--" + boundary);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes("Content-Disposition: form-data; name="" + key + ""; filename="" + srcData[key].filename + """);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes("Content-Type: " + srcData[key].mimeType);
					//Content-Type;
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeUTFBytes(httpSeparator);
					this.request.data.writeBytes(srcData[key].data, 0, srcData[key].data.length);
					this.request.data.writeUTFBytes(httpSeparator);
				}
			}
		}

		/**
		 * 加载要POST的参数
		 */
		private function loadPostParams(param_string:String):void
		{
			if (param_string != null)
			{
				var name_value_pairs:Array = param_string.split("&");

				var key:String = "";
				var val:String = "";

				for (var i:Number = 0; i < name_value_pairs.length; i++)
				{
					var name_value:String = String(name_value_pairs[i]);
					var index_of_equals:Number = name_value.indexOf("=");
					if (index_of_equals > 0)
					{
						key = decodeURIComponent(name_value.substring(0,index_of_equals));
						val = decodeURIComponent(name_value.substr(index_of_equals + 1));
						this.postParams[key] = val;
					}
				}
			}
		}

		public function debug(debugInfo:String):void
		{
			trace(debugInfo);
			ExternalInterface.call("console.log",debugInfo.replace("'","\'"));
		}
		
		private function loadImg(url:String)
		{
			var loader:Loader = new Loader();
			loader.load(new URLRequest(url));
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onCompleteloadImg);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler1);
		}
		function onCompleteloadImg(e:Event):void
		{
			var button:SimpleButton = new SimpleButton(e.currentTarget.content,e.currentTarget.content,e.currentTarget.content,e.currentTarget.content);
			button.x = 0;
			button.y = 0;
			loadImgCb(addChild(button));
		}
		private function ioErrorHandler1(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
			loadImg(buttonImage);
        }

	}


}


 

调用flash的js

/**
 * ASUploader: http://ASUploader.googlecode.com
 * 
 * @copyright (c) 2011 
 * @author Joseph Chen
 * @release MIT License:
 * @link http://www.opensource.org/licenses/mit-license.php
 */
function ASUploader(setting) {
	this.setting	= setting;
	this.movieId	= 0;
	this.swfObject	= false;
	
	//init setting
	this.init = function() {
		// flash settings
		this.movieName			= 'ASUploader_' + this.movieId;
		this.placeHolderId		= 'ASUploaderPlaceHolder';
		this.flashUrl			= 'ASUploader.swf';
		this.swfVersionStr		= '10.0.0';
		//this.xiSwfUrlStr		= 'playerProductInstall.swf';
		// flash display
		this.lableText			= 'Please Select Files';
		this.buttonTextStyle	= 'display:block;text-align:left;color: #000000;font-size: 20px;';
		this.width				= 100;
		this.height				= 30;
		this.textTopPadding		= 0;
		this.textLeftPadding	= 0;
		// upload server settings
		this.uploadUrl			= 'upload.php';
		this.queryString		= '';
		this.postParams			= '';
		// file settings
		this.fileTypesDesc		= 'All Files';//Image
		this.fileTypes			= '*.*';//*.png;*.jpg;*.gif
		this.fileSizeLimit		= 0;// zero means 'unlimited'
		this.fileUploadLimit	= 0;
		this.fileQueueLimit		= 0;
		this.multiFiles			= true;
		this.buttonImage		= "";
		//Event Handlers
		this.fileSelectStartHandler = null;
		this.fileSelectCompleteHandler = null;
		this.uploadCompleteHandler = 'completeCallback';
		this.uploadProgressHandler = 'uploadProgressCallbak';
		
		for (var name in setting) 
		{
			if (this.setting[name] != undefined) 
			{
				this[name] = this.setting[name];
			} else if (this[name] == undefined) 
			{
				continue;
			}
		}
		
		// 要在setting初始化后设置下面的参
		this.postParams	= this.buildParams(setting.postParams);
		this.flashParams = 
		{
			quality	: 'high',
			bgcolor	: '#ffffff',
			allowscriptaccess	: 'always',
			allowfullscreen		: 'true'			
		};
		this.flashAttributes = 
		{
			id		: this.movieName,
			name	: this.movieName,
			align	: 'middle'
		}
		return this;
	};
	// 获取传递给swf的参数
	this.getFlashVars = function() {
		return flashvars = {
			movieName		: this.movieName,
			swfVersionStr	: this.swfVersionStr,
			lableText		: this.lableText,
			width			: this.width,
			height			: this.height,
			textTopPadding	: this.textTopPadding,
			textLeftPadding	: this.textLeftPadding,
			buttonTextStyle	: this.buttonTextStyle,
			uploadUrl		: this.uploadUrl,
			queryString		: this.queryString,
			postParams		: this.postParams,
			fileTypesDesc	: this.fileTypesDesc,
			buttonImage		: this.buttonImage,
			fileTypes		: this.fileTypes,
			fileSizeLimit	: this.fileSizeLimit,
			fileUploadLimit	: this.fileUploadLimit,
			fileSizeLimit	: this.fileSizeLimit,
			fileQueueLimit	: this.fileQueueLimit,
			multiFiles		: this.multiFiles,
			buttonImage		: this.buttonImage,
			uploadProgressHandler	: this.uploadProgressHandler,
			uploadCompleteHandler	: this.uploadCompleteHandler,
			fileSelectCompleteHandler	: this.fileSelectCompleteHandler,
			fileSelectStartHandler	: this.fileSelectStartHandler			
		};
	};
	
	this.getFlashVarsString = function() {
		flashvars = this.getFlashVars();
		var string = '';
		for (var key in flashvars) {
			try{
				if (flashvars[key] == null) flashvars[key] = '';
				if (string == '') {
					string += key+'='+encodeURIComponent(flashvars[key].toString());
				} else {
					string += '&' +key+ '=' + encodeURIComponent(flashvars[key].toString());
				}
			}catch(e){
				alert(e)
			}
		}
		return string;
	};
	
	// 创建FLASH
	this.create = function (movieName) {
		if (movieName) {
			this.movieName = movieName;
		}
		var flashHtml = '<object align="'+this.flashAttributes.align+'" width="'+this.width+'" height="'+this.height+'"'
				+ ' id="'+this.flashAttributes.id+'" name="'+this.flashAttributes.name+'"'
				+ '  classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">'
				+ '<param name="movie" value="'+this.flashUrl+'" />'
				+ '<param name="allowNetworking" value="all" />'
				+ '<param name="quality" value="'+this.flashParams.quality+'">'
				+ '<param name="bgcolor" value="'+this.flashParams.bgcolor+'">'
				+ '<param name="allowfullscreen" value="'+this.flashParams.allowfullscreen+'">'
				+ '<param name="allowscriptaccess" value="'+this.flashParams.allowscriptaccess+'">'
				+ '<param name="flashvars" value="'+this.getFlashVarsString()+'">'
				+ '	<!--[if !IE]>-->'
				+ '	<object type="application/x-shockwave-flash" data="'+this.flashUrl+'"'
				+ '	 width="'+this.width+'" height="'+this.height+'"'
				+ '	 id="'+this.flashAttributes.id+'" name="'+this.flashAttributes.name+'"'
				+ '	 style="visibility: visible;">'
				+ '	<param name="quality" value="'+this.flashParams.quality+'">'
				+ '	<param name="bgcolor" value="'+this.flashParams.bgcolor+'">'
				+ '	<param name="menu" value="false" />'
				+ ' <param name="allowNetworking" value="all" />'
				+ '	<param name="wmode" value="opaque" />'
				+ '	<param name="allowfullscreen" value="'+this.flashParams.allowfullscreen+'">'
				+ '	<param name="allowscriptaccess" value="'+this.flashParams.allowscriptaccess+'">'
				+ '	<param name="flashvars" value="'+this.getFlashVarsString()+'">'
				+ '	<!--<![endif]-->
'
				+ '	<!--[if gte IE 6]>-->
'
				+ '	<p>Either scripts and active content are not permitted to run or Adobe Flash Player version'
				+ '	'+this.swfVersionStr+' or greater is not installed.'
				+ '	</p>
'
				+ '	<!--<![endif]-->
'
				+ '	<a href="http://www.adobe.com/go/getflashplayer">'
				+ '	<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"'
				+ ' alt="Get Adobe Flash Player" /></a>
'
				+ '	<!--[if gte IE 6]>-->
'
				+ '	</object>
'
				+ '	<!--<![endif]-->
'
				+ '</object>';
		
		var targetElement, tempParent;
	
		// Make sure an element with the ID we are going to use doesn't already exist
		if (document.getElementById(this.movieName) !== null) {
			throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
		}
	
		// Get the element where we will be placing the flash movie
		targetElement = document.getElementById(this.placeHolderId);
	
		if (targetElement == undefined) {
			throw "Could not find the placeholder element: " + this.placeHolderId;
		}
		
		tempParent = document.getElementById(movieName+'_swf');		
		// Append the container and embed the flash
		if(!tempParent) 
		{
			tempParent = document.createElement("div");
			// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
			tempParent.innerHTML = flashHtml;
			//targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
			targetElement.parentNode.appendChild(tempParent.firstChild);
		}else 
			tempParent.innerHTML = flashHtml;
	
		// Fix IE Flash/Form bug
		if (window[this.movieName] == undefined) {
			window[this.movieName] = this.getMovieElement();
		}
		return this;
	};
	// 组装传递给swf的额外参数(用来swf向服务器程序提交的参数
	this.buildParams = function (params) {
		var paramPairs = [];

		if (typeof(params) === 'object') {
			for (var key in params) {
				paramPairs.push(key.toString() + '=' + params[key].toString());
			}
		}

		return paramPairs.join('&'); 
	};
	// 开始上传
	this.upload = function() {
		if (!this.flash) {
			this.flash = this.getObjectById(this.movieName);
		}
		if (this.flash && this.flash.upload != undefined) {
			this.flash.upload();
		}
		return this;
	};
	// 开始上传
	this.selectFiles = function(e) {
		if (!this.flash) {
			this.flash = this.getObjectById(this.movieName);
		}
		if (this.flash && this.flash.selectFiles != undefined) {
			this.flash.selectFiles(e);
		}
		return this;
	};
	// 设置参数
	this.setParam = function(key, value) {
		if (!this.flash) {
			this.flash = this.getObjectById(this.movieName);
		}
		if (this.flash && this.flash.setParam != undefined) {
			this.flash.setParam(key, value+"");
		}
		return this;
	};
	// 向swf发送要提交的参数数据 
	this.sendPostDataToAs = function(data) {
		if (!this.flash) {
			this.flash = this.getObjectById(this.movieName);
		}
		if (this.flash && this.flash.sendPostDataToAs != undefined) {
			this.flash.sendPostDataToAs();
		}
		return this;
	};
	
	this.getObjectById = function(id) {
		var r = null;
		var o = document.getElementById(id);
		if (o && o.nodeName == "OBJECT") {
			if (typeof o.SetVariable != 'undefined') {
				r = o;
			}
			else {
				var n = o.getElementsByTagName('OBJECT')[0];
				if (n) {
					r = n;
				}
			}
		}
		return r;
	};
	
	this.getMovieElement = function() {
		if (this.movieElement == undefined) {
			this.movieElement = document.getElementById(this.movieName);
		}
	
		if (this.movieElement === null) {
			throw "Could not find Flash element";
		}
		
		return this.movieElement;
	};
	
	
	// init
	this.init();
};


 

调用的js代码:

if(typeof(hostname)=='undefined'){
						hostname = window.location.href.replace(/^http://([^/]+)/?.*$/,"$1");
					} 
					ASUploaderImg = (new ASUploader({
                        movieName			: "ASUploaderFlash",
                        uploadUrl			: "index.php?m=upload_chat",
                        lableText			: "文件", 
                        textTopPadding		: 0,
                        textLeftPadding		: 0,
                        width				: 16,
                        height				: 16,
                        fileTypesDesc		: "文件",
                        fileTypes			: "*.jpg;*.gif;*.png",
                        postParams			: {'multi_merge':1, "more_params":"much more"},
                        fileQueueLimit		: 5,
                        multiFiles			: false,
						buttonImage			: 'http://'+hostname+'/images/green/pic.jpg',
                        uploadCompleteHandler: "uploadCompleteCallback",
                        uploadProgressHandler: "uploadProgressCallback",
						fileSelectCompleteHandler : "fileSelected"
                    }))
                    .create('ASUploaderFlash');	

我的QQ群:

PHPer&Webgame&移动开发,群号:95303036

我的QQ群:
 
PHPer&Webgame&移动开发,群号:95303036

原文地址:https://www.cnblogs.com/lein317/p/5067597.html