Actionscript3 文件上传组件制作

现在网站开发中,使用flash作为上传工具已经很普遍了。他的优势也是不言而喻的。其中我最钟意的一点就是可以看到上传进度。

前段时间,用as3写了个swf跟页面元素交互上传文件到服务器。



先来个效果图看看。


Html页面上部署swf:

<div class="container" align="left" style="padding-top:0;">

  <object id="longan" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="500" height="65">

    <param name="movie" value="${base}/resource/component/upload/longan.swf" />

    <param name="quality" value="high" />

<param name="bgcolor" value="#fdf7f7" />

    <embed src="${base}/resource/component/upload/longan.swf" id="longan" bgcolor="#bee2c2" name="longan" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="500" height="65" ></embed>

  </object>

</div>

然后是js设置:

<script language="JavaScript" type="text/javascript">

/*获取swf*/

function getFlashMovie() {

var movieName="longan";

    if (window.document[movieName]){

    return window.document[movieName];

  }else if (navigator.appName.indexOf("Microsoft")==-1){

    if (document.embeds && document.embeds[movieName])

    return document.embeds[movieName];

  }else{

    return document.getElementById(movieName);

  }

}


var setting={

	url:"${base}/document/upload;jsessionid=${sessionID}",//这里换成你想要的路径
	fileTag:"select:*.txt;*.doc;*.docx;*.xls;*.ppt;*.rar;*.zip",
	fileExt:"${allowExt}",//可以上传的文件类型*.txt;*.doc;*.docx;*.xls;*.ppt;*.rar;*.zip
	fileName:"upload_file",//file
	maxFileNumber:1,
	maxSize:${maxUploadSize},//最大上传文件大小
	logoText:"欢迎使用Longan上传工具!",//提示信息
	params:"doc_id=${doc_id}&flash=1",//参数,格式:doc_id=1
	response:"File.response",//返回数据时回调
	debug:true //debug模式
}

//debug模式下的回调函数,名字不能更改
function longan_debug(s){

	document.getElementById("debug").innerHTML+=s;

}


function init(){

	try{

		//调用swf中的setParams() 这个是在swf中定义的。
		//之所以要不断调用,是因为可能swf还没有加载成功。
		getFlashMovie().setParams(setting);

	}catch(e){
		setTimeout("File.init();",2000);
	}
}

//初始化上传组件
window.onload=init;
</script>


好了,看下actionscript 中是怎样与 js交互的:

/*
===============================================================

JS 交互

===============================================================
*/

public function initJS():void{

	ExternalInterface.addCallback("setParams",initParams);

}

public function initParams(s:Object):void{

	this.url=s.url;
	this.fileExt=s.fileExt;
	this.fileName=s.fileName;
	this.fileTag=s.fileTag;
	this.maxFileNumber=s.maxFileNumber;
	this.maxSize=s.maxSize;
	this.debug=s.debug;
	this.logoText=s.logoText;
	this.params=s.params;
	this.response=s.response;

	if(this.logoText)
	this.label.text=this.logoText;

	if(this.debug){
		toJSDebug(getParamsInfo());
	}

}


public function toJSDebug(s:String):void{

	if(ExternalInterface.available){
		ExternalInterface.call("longan_debug",s);
	}

}


public function getParamsInfo():String{

	var s:String="参数设置成功!<br />";
	s+="URL:"+url+"<br />";
	s+="文件格式:"+fileExt+"<br />";
	s+="文件数:"+maxFileNumber+"<br />";
	s+="文件大小限制:"+maxSize+"<br />";
	s+="debug模式:"+debug+"<br />";
	s+="post参数:"+params+"<br />";
	s+="server response function:"+response+"<br />";
	return s+"<br />";

}

/*
=================================================================

end    JS 交互

=================================================================
*/


在ExternalInterface 中添加对外api。
上传文件的代码:

/**
 * 上传文件
 * */

public function sendFile(e:MouseEvent):void{

	if(this.url==""){
		error("上传的URL不明确!");
		return ;
	}

	data.decode(this.params);
	request = new URLRequest(this.url);
	request.method=URLRequestMethod.POST;
	request.data=data;

	this.timeout=new Date().time;
	this.file.upload(request,this.fileName);

	addProgress();

	this.loading=true;
	this.sendButton.enabled=false;
	this.button.enabled=false;
}

----------------------------------------------------------
注意点:
----------------------------------------------------------
1.设置swf的上传路径时,一般需要验证session是否已经有登录,不然不能接收上传的文件。这时就需要添加一个sessionId的参数,比如在jsp中,可以这样:
/document/upload;jsessionid=${sessionID}

2.在<embed/>标签中一定要添加 name 属性,不然js是不能获取到swf组件的。

3.上传时,需要将 URLRequest的requestMethod设置为POST


这里不给上传附件。。

完整的as代码我就直接帖出来了。。

package
{
 import fl.controls.Button;
 import fl.controls.Label;
 import fl.controls.ProgressBar;
 import fl.controls.ProgressBarMode;
 import fl.controls.progressBarClasses.IndeterminateBar;
 import fl.managers.StyleManager;
 
 import flash.display.Sprite;
 import flash.events.DataEvent;
 import flash.events.Event;
 import flash.events.IOErrorEvent;
 import flash.events.MouseEvent;
 import flash.events.ProgressEvent;
 import flash.external.ExternalInterface;
 import flash.net.FileFilter;
 import flash.net.FileReference;
 import flash.net.URLRequest;
 import flash.net.URLRequestMethod;
 import flash.net.URLVariables;
 import flash.text.TextFormat;
 
 import mx.events.ModuleEvent;
 
 /**
  * <script type="text/javascript" src="js/file.longan.1.0.js"></script><div><a href="#" onclick="File.toAS();">12465</a></div><div id="debug"></div>
  * 
  * 
  * longan上传工具(flash版)
  * 带进度条的上传工具哈。
  * 2011-12-27 by 集成显卡
  */
 [SWF(width="500", height="65", backgroundColor="#fdf7f7")]//定义场景大小
 public class longan extends Sprite{
  /*
  外部设置的参数
  */
  //上传地址
  private var url:String="";
  private var fileTag:String="select file";
  private var fileExt:String="*.*";
  //上传文件的name
  private var fileName:String="fileArea";
  private var maxFileNumber:int=1;//最大文件数
  private var debug:Boolean=false;//是否开启debug模式
  private var maxSize:uint=10*1024*1024;
  private var logoText:String="welcome! by:集成显卡";//初始时显示的文字
  private var params:String="version=1.0";
  private var response:String="";//返回数据时的函数
  
  /*
  内置参数
   * */
  private var L:Object={select:"选择文件",send:"上传"};
  private var loading:Boolean=false;
  private var fileSize:uint=0;//文件大小
  private var curSize:uint=0;//当前上传的大小
  private var curFile:int=0;
  private var data:URLVariables = new URLVariables();
  private var timeout:Number;
  
  /*
  组件
   * */
  private var request:URLRequest;
  private var button:Button;
  private var sendButton:Button;
  //进度条
  private var progressBar:ProgressBar;
  private var label:Label;
  private var infoLabel:Label;
  //上传主要
  private var file:FileReference;
  
  public function longan(){
   init();
  }

  public function init():void{
   initStyle();
   initUI();
   initJS();
  }

  /*
  ===============================================================================
  JS 交互
  ===============================================================================
  */
  public function initJS():void{
   ExternalInterface.addCallback("setParams",initParams);
  }
  public function initParams(s:Object):void{
   this.url=s.url;
   this.fileExt=s.fileExt;
   this.fileName=s.fileName;
   this.fileTag=s.fileTag;
   this.maxFileNumber=s.maxFileNumber;
   this.maxSize=s.maxSize;
   this.debug=s.debug;
   this.logoText=s.logoText;
   this.params=s.params;
   this.response=s.response;
   
   if(this.logoText)
    this.label.text=this.logoText;
   
   if(this.debug){
    toJSDebug(getParamsInfo());
   }
  }
  
  public function toJSDebug(s:String):void{
   if(ExternalInterface.available){
    ExternalInterface.call("longan_debug",s);
   }
  }
  
  public function getParamsInfo():String{
   var s:String="参数设置成功!<br />";
   s+="URL:"+url+"<br />";
   s+="文件格式:"+fileExt+"<br />";
   s+="文件数:"+maxFileNumber+"<br />";
   s+="文件大小限制:"+maxSize+"<br />";
   s+="debug模式:"+debug+"<br />";
   s+="post参数:"+params+"<br />";
   s+="server response function:"+response+"<br />";
   return s+"<br />";
  }
  /*
  ===============================================================================
  end    JS 交互
  ===============================================================================
  */

  /**
   * 设置字体
   * */
  public function initStyle():void{
   var txt:TextFormat=new TextFormat();
   txt.size=13;
   StyleManager.setStyle("textFormat",txt);
  }
  
  /**
   * 设置界面
   * */
  public function initUI():void{
   this.button=new Button();
   this.button.label=L.select;
   this.button.width=80;
   this.button.x=340;
   this.button.y=5;
   this.button.addEventListener(MouseEvent.CLICK,selectFile);
    
   this.sendButton=new Button();
   this.sendButton.label=L.send;
   this.sendButton.width=60;
   this.sendButton.x=430;
   this.sendButton.y=5;
   this.sendButton.addEventListener(MouseEvent.CLICK,sendFile);
   this.sendButton.enabled=loading;
   
   this.label=new Label();
   this.label.text="";
   this.label.x=5;
   this.label.y=5;
   this.label.height=30;
   this.label.width=310;
   
   this.infoLabel=new Label();
   this.infoLabel.text="";
   this.infoLabel.x=5;this.infoLabel.y=45;
   this.infoLabel.width=480;
   
   this.progressBar=new ProgressBar();
   this.progressBar.x=5;
   this.progressBar.y=30;
   this.progressBar.setSize(480,15);
   this.progressBar.mode=ProgressBarMode.MANUAL;
   this.progressBar.indeterminate=false;
   
   addChild(label);
   addChild(button);
   addChild(sendButton);
   addChild(this.infoLabel);
  }
  
  /**
   * 选择文件
   * */
  public function selectFile(e:MouseEvent):void{
   if(!canUpload()){
    error("已经达到了上传数量限制!不能再上传文件了");
    return ;  
   }
   if(!loading){
    file = new FileReference();
    file.addEventListener(ProgressEvent.PROGRESS, onProgress);  
    file.addEventListener(Event.SELECT, onSelect);  
    file.addEventListener(Event.COMPLETE, completeHandle);
    file.addEventListener(IOErrorEvent.IO_ERROR,onLoadError);
    file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,returnData);
    this.file.browse(new Array(new FileFilter(fileTag,fileExt)));
   }
  }
  
  /**是否可以上传*/
  public function canUpload():Boolean{
   return curFile<maxFileNumber;
  }
  
  public function error(s:String):void{
   infoLabel.htmlText="<font color='#fd5555'>"+s+"</font>";
  }
  
  public function onProgress(e:ProgressEvent):void{
   curSize=e.bytesLoaded;
   infoLabel.text = "已上传 "+Math.round(e.bytesLoaded/1024) + " / "+Math.round(e.bytesTotal/1024)+" KB";
   progressBar.setProgress(curSize,fileSize);
  }
  
  public function onLoadError(e:IOErrorEvent):void{
   this.button.enabled=true;
   this.loading=false;
   error("上传出错!"+e);
  }
  
  public function onSelect(e:Event):void{
   var name:String=file.name;
   this.fileSize=file.size;
   this.label.text=name+"    大小:"+Math.round(this.fileSize/1024)+" KB";
   if(allowSize()){
    this.sendButton.enabled=true;
   }else{
    error("选择的文件太大,最大的文件大小为:"+this.maxSize/1024+" Kb");
    return ;
   }
  }
  
  public function completeHandle(e:Event):void{
   this.button.enabled=true;
   this.loading=false;
   error("完成!用时:"+(new Date().time-timeout)+" 毫秒");
   this.curFile++;
  }
  
  public function returnData(e:DataEvent):void{
   trace(e.data);
   if(this.debug){
    toJSDebug("upload success!"+e.data);
   }
   if(ExternalInterface.available){
    ExternalInterface.call(response,e.data);
   }
  }
  
  /**
   * 上传文件
   * */
  public function sendFile(e:MouseEvent):void{
   if(this.url==""){
    error("上传的URL不明确!");
    return ;
   }
   data.decode(this.params);
   request = new URLRequest(this.url);
   request.method=URLRequestMethod.POST;
   request.data=data;
   this.timeout=new Date().time;
   this.file.upload(request,this.fileName);
   addProgress();
   this.loading=true;
   this.sendButton.enabled=false;
   this.button.enabled=false;
  }
  public function addProgress():void{
   if(curFile==0){
    addChild(progressBar);
   }
  }
  public function allowSize():Boolean{
   return this.fileSize<=this.maxSize;
  }
  
 }
}


posted @ 2012-08-14 13:44  集成显卡  阅读(405)  评论(0编辑  收藏  举报