实现多个文件同时上传

做 上传图片功能的时候,经常会遇到这样一个问题,有时候可能需要一次上传多张图片,而用html中默认的上控件,却只能选定一个文件,且不能对文件的后缀进 行筛选。需要一次上传多个文件的需求,往往可以通过添加多个上传控件来予以满足,比如百度空间的相册上传功能就是这样来实现的。不过,要实现对上传文件后 缀的过滤,却始终无法通过常规的方法予以实现。
这两个功能真的这么难以实现吗?非也,看看flickr的上传功能即可获得明确的答复。
为什么能实现这样的功能呢?google了一下,谜底就揭晓了。原来,这是利用了flash的若干功能,通过javascript和 actionscript的交互得以实现的。js和as的通讯以前有研究过,所以要实现起来非常简单。再到flash里边f1一下,关于上传方面的相关只 是也差不多了解了,因此,接下来的事情的就只是顺水推舟的事情了。
最重要的还是flash代码的完善,最后的成果如下:

// MultiUploader.fla
import flash.net.FileReferenceList;
import flash.net.FileReference;
import flash.external.ExternalInterface;

// 设置as中函数和js调用时的映射关系
ExternalInterface.addCallback("fu_open_dialog", null, openDialog);
ExternalInterface.addCallback("fu_begin_upload", null, beginUpload);

// 可以通过html页面里边设置FlashVars里边的upload_url来更改上传文件的路径
var uploadUrl:String = typeof(_root.upload_url) == "undefined" ? "FlashUpload.ashx" : _root.upload_url;
var listener:Object = new Object();
// 选择文件后,会视图调用js函数onUploaderSelect,并将文件列表传入进去,便于js进一步做一些逻辑控制
listener.onSelect = function(fileRefList:FileReferenceList) {
    ExternalInterface.call("onUploaderSelect", fileRefList.fileList);
};

var fileRefList:FileReferenceList = null;
var imageTypes:Object = new Object();
imageTypes.description = "Images (*.jpg, *.jpeg, *.gif, *.png)"; // 上传文件类型说明
imageTypes.extension = "*.jpg; *.jpeg; *.gif; *.png"; // 控制上传文件类型

// 显示文件打开窗口
function openDialog():Void {
    if (fileRefList == null) {
        fileRefList = new FileReferenceList();
        fileRefList.addListener(listener);
    }
    fileRefList.browse([imageTypes]);
}
// 开始上传
function beginUpload():Void {
    var lis = new Object();
    // 每上传完一个文件后调用js函数onUploaderComplete
    lis.onComplete = function(file:FileReference):Void {
        ExternalInterface.call("onUploaderComplete", file.name);
    };
    // 处理上传地址的http状态错误。比如404等。
    lis.onHTTPError = function(file:FileReference, httpError: Number):Void {
        ExternalInterface.call("onUploaderHTTPError", httpError, file.name);
    }
   
    var list:Array = fileRefList.fileList;
    var item:FileReference;
    // 最终还是将文件分单次传到指定上传页面进行处理
    for(var i:Number = 0; i < list.length; i++) {
        item = list[i];
        item.addListener(lis);
        item.upload(uploadUrl);
    }
}

至于客户端的处理,只需要将as中自动调用的几个js函数实现即可。最后的页面代码如下:




Insert title here










这次功能的实现上,在其他方面都还很顺利得以实现,反而是在createUploadFlash这个函数的实现上遇到了一些麻烦。因为最后返回flash 对象的时候经常不被正常地识别。如果这段代码不用js生成,那么用document.flashObject和 dobument.getElementById('flashObject')都可以正常识别flashObject,但动态生成以后,用后者就不能正 常被访问到了,可能的原因是加载需要一定的延时,有待研究。

通过这样的方式实现文件上传,一则能解决掉多选问题和文件类型过滤问题,另外也能实现文件的无刷新上传,可以在图片上传的同时去进行别的工作。

你可能感兴趣的:(js心得)