Flash8中提供了FileReference类,利用它我们就能使用Flash做文件上传的用户端界面,然后结合其他Web程序,比如PHP,ASP,JSP,C#等,就可以实现文件上传了.
先看看这个效果
效果展示
在这个例子中,我们使用Flash做界面,然后让用户从本机选择要上传到服务器的文件(这里限定为只传纯文本*.txt文件,其实是其他类型文件也可以上传,这里要演示,所以只传文本文件).另外,上传之后,我们再使用loadVars把上传的文件内容加载下来,并现在是在Flash里.
使用说明:
- 文件名不要使用中文!!!
- 点浏览按钮选择要上传的文件(这里限定为大小不超过1M的纯文本*.txt文件)
- 点上传按钮,上传到服务器,ProgressBar组件会显示上传进度
- 上传完成后会显示出[查看该文件内容按钮],点击它,会从服务器读取上传的文件
- 如果读取成功,则会在最下面出现TextArea组件,并展示加载的内容.
- 任何时候出现了错误,则可能会出现Alert组件并展示错误信息.
代码分析
这里的主要是利用FileReference类的相关属性和方法,选择上传的文件,然后服务器后台接收信息,并保存文件.
SWF里的ActionScript代码
AS Codeimport flash.net.FileReference; import mx.controls.Alert; System.useCodepage = true; var allTypes:Array = new Array (); // 文件类型 var textTypes:Object = new Object (); textTypes.description = "Text Files (*.txt)"; textTypes.extension = "*.txt"; allTypes.push (textTypes); var host:String = "http://www.4nothing.net/flashexample/as-php/"; var listener:Object = new Object (); // 当选中文件时 listener.onSelect = function (file:FileReference):Void { if (file.size > 1024 * 1024) { errLog ("文件超过了1M"); path_txt.text = "请先选择要上传的文件"; return; } path_txt.text = "你选择的文件是 [" + file.name + "]"; upload_btn.enabled = true; }; // 当取消时 listener.onCancel = function (file:FileReference):Void { path_txt.text = "请先选择要上传的文件"; upload_btn.enabled = false; }; // 上传开始时调用 listener.onOpen = function (file:FileReference):Void { showResult (false); browse_btn.enabled = false; upload_btn.enabled = false; my_pb.setProgress (0, 0); }; // 上传中 listener.onProgress = function (file:FileReference, bytesLoaded:Number, bytesTotal:Number):Void { my_pb.setProgress (bytesLoaded, bytesTotal); }; // 结束 listener.onComplete = function (file:FileReference):Void { browse_btn.enabled = true; upload_btn.enabled = true; view_btn._visible = true; }; // HTTP错误 listener.onHTTPError = function (file:FileReference):Void { errLog ("onHTTPError: " + file.name); }; // IO错误 listener.onIOError = function (file:FileReference):Void { errLog ("onIOError: " + file.name); }; // 安全限制 listener.onSecurityError = function (file:FileReference, errorString:String):Void { errLog ("onSecurityError: " + file.name + " errorString: " + errorString); }; // 用户浏览和上传按钮的监听对象 var browseObj:Object = new Object (); browseObj.click = function () { fileRef.browse (allTypes); }; var uploadObj:Object = new Object (); uploadObj.click = function () { if (!fileRef.upload (host + "upload.php")) { errLog ("Upload dialog failed to open."); } }; // 查看文件内容 var my_lv:LoadVars = new LoadVars (); my_lv.onLoad = function (success) { if (success) { trace ("ok"); trace (this["content"]); if (Number (this["code"]) == 1) { content_txt._visible = true; content_txt.text = this["content"]; } else { errLog ("获取信息失败!"); } } else { trace ("error"); errLog ("获取信息失败le!"); } view_btn.enabled = true; browse_btn.enabled = true; upload_btn.enabled = true; }; var viewObj:Object = new Object (); viewObj.click = function () { view_btn.enabled = false; browse_btn.enabled = false; upload_btn.enabled = false; my_lv.load (host+"checkfile.php?filename=" + fileRef.name + "&time=" + getDateStr ()); }; function getDateStr ():String { return new Date ().toString (); } var fileRef:FileReference = new FileReference (); // 隐藏查看按钮和内容面板 function showResult (flag:Boolean) { view_btn._visible = false; content_txt._visible = false; } // 错误提示 function errLog (msg:String) { Alert.show (msg, "出错了!", Alert.OK); } function init () { // 添加监听器 fileRef.addListener (listener); browse_btn.addEventListener ("click", browseObj); upload_btn.addEventListener ("click", uploadObj); view_btn.addEventListener ("click", viewObj); path_txt.editable = false; path_txt.text = "请先选择要上传的文件"; // 进度条信息 my_pb.mode = "manual"; my_pb.label = "上传进度:%1 / %2 字节"; my_pb.labelPlacement = "top"; upload_btn.enabled = false; showResult (false); } stop (); init ();
因为基本都是使用的组件,所以使用的addEventListener比较多.不过难度并不大.
服务器端php代码
upload.php
PHP Codeerror_reporting(E_ALL ^ E_NOTICE); /** * 通过SWF上传来的文件具有如下结构 *$_FILES['Filedata'] -->名称都是Filedata,注意大小写 *$_FILES['Filedata']['name'] -->上传的文件名,包括扩展名 *$_FILES['Filedata']['type'] -->文件类型,不要把它跟文件扩展名混为一谈,另外这项内容不一定可用。 *$_FILES['Filedata']['tmp_name'] -->保存在服务器上的临时文件名。因为PHP会把上传的文件先保存在临时文件夹内 *$_FILES['Filedata']['size'] -->已上传文件大小 *$_FILES['Filedata']['error'] -->出现的错误 */ $file = $_FILES['Filedata']; // 直接访问本页面而没有上传文件时退出 if(empty($file)) { exit(); } $name = $file['name']; // 获取扩展名 $ext = strrchr($name,'.'); if($ext === false) { exit(); } // 限定为txt if($ext != ".txt") { exit(); } //检查文件大小 if($file['size'] > 1024 * 1024) { exit(); } // 保存路径 $uploaddir = './upload/'; // 实际保存的文件信息 $uploadfile = $uploaddir . basename($name); move_uploaded_file($file['tmp_name'], $uploadfile);
需要注意的一点就是Flash上传文件时,服务器端接收到的名称是$_FILES['Filedata'],然后其他操作,包括检验文件类型,文件大小,及相应的保存工作也是比较简单的.可能有人会说,这里为什么要再次检查文件大小,文件扩展名,因为我们要牢记一句话:客户端传递来的信息都是不安全的!
源文件下载
- FLA文件:as_php_upload.fla
- SWF文件:as_php_upload.swf
这里不提供php文件的下载,如果需要,你可以直接从本页上复制,或者Mail我,本页底端有我的邮箱.