多选图片一次上传

做上传图片功能的时候,经常会遇到这样一个问题,有时候可能需要一次上传多张图片,而用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函数实现即可。最后的页面代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<input type="button" value="open" onclick="openUploadDialog();"/>
<input type="button" value="upload" onclick="uploadFiles();"/>

<div id="flashPanel"></div>

</body>
<script type="text/javascript">
var flash = createUploadFlash(document.getElementById('flashPanel'), 'upload.swf', 'FlashUpload.ashx')
// 打开文件对话框
function openUploadDialog() {
flash.fu_open_dialog();
}
// 上传文件
function uploadFiles() {
flash.fu_begin_upload();
}

// 选择文件以后
function onUploaderSelect(list) {
alert(list);
}

// 上传完一个文件以后
function onUploaderComplete(name) {
alert(name);
}

// 上传文件出错时
function onUploaderHTTPError(number, name) {
switch (number) {
case 413:
alert("文件" + name + "大于10K,不能上传");
break;
}
}
/**
* 创建一个flash。主要是在ie7里边需要用鼠标点击才能激活flash,通过动态生成flash的方式可以绕过这一点。
* @param panel 用来放置flash的div
* @param flashUrl flash的地址
* @param uploadUrl 用来出来上传文件的地址
*/
function createUploadFlash(panel, flashUrl, uploadUrl){
var code = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="0" height="0" id="flashObject" align="middle">\
<param name="allowScriptAccess" value="sameDomain" />\
<param name="movie" value="' + flashUrl + '" />\
<param name="quality" value="high" />\
<param name="bgcolor" value="#ffffff" />\
<param name="FlashVars" value="upload_url=' + uploadUrl + '" />\
<embed src="' + flashUrl + '" quality="high" bgcolor="#ffffff" width="0" height="0" name="flashObject" FlashVars="upload_url=' + uploadUrl + '" align="middle" allowScriptAccess="sameDomain" id="flashObject" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />\
</object>';
panel.innerHTML = code;
return window.document.flashObject;
}

</script>
</html>

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

通过这样的方式实现文件上传,一则能解决掉多选问题和文件类型过滤问题,另外也能实现文件的无刷新上传,可以在图片上传的同时去进行别的工作。
本实例采用的是Uploadify上传插件,.NET程序,源程序是从网上找的,但是有Bug,已经修改好,并标有部分注释。绝对好用,支持单文件、多文件上传,支持大文件上传,已经过多方面测试,保证好用。 以下附上Uploadify部分常用的参数介绍,要看全部的就去看其API文件了,一般在下载的包里都有。  uploader : uploadify.swf 文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后弹出打开文件对话框,默认值:uploadify.swf。   script : 后台处理程序的相对路径 。默认值:uploadify.php   checkScript :用来判断上传选择的文件在服务器是否存在的后台处理程序的相对路径   fileDataName :设置一个名字,在服务器处理程序中根据该名字来取上传文件的数据。默认为Filedata   method : 提交方式Post 或Get 默认为Post   scriptAccess :flash脚本文件的访问模式,如果在本地测试设置为always,默认值:sameDomain   folder : 上传文件存放的目录 。   queueID : 文件队列的ID,该ID与存放文件队列的div的ID一致。   queueSizeLimit : 当允许多文件生成时,设置选择文件的个数,默认值:999 。   multi : 设置为true时可以上传多个文件。   auto : 设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传 。   fileDesc : 这个属性值必须设置fileExt属性后才有效,用来设置选择文件对话框中的提示文本,如设置fileDesc为“请选择rar doc pdf文件”,打开文件选择框效果如下图:   fileExt : 设置可以选择的文件的类型,格式如:'*.doc;*.pdf;*.rar' 。   sizeLimit : 上传文件的大小限制 。   simUploadLimit : 允许同时上传的个数 默认值:1 。   buttonText : 浏览按钮的文本,默认值:BROWSE 。   buttonImg : 浏览按钮的图片的路径 。   hideButton : 设置为true则隐藏浏览按钮的图片 。   rollover : 值为true和false,设置为true时当鼠标移到浏览按钮上时有反转效果。   width : 设置浏览按钮的宽度 ,默认值:110。   height : 设置浏览按钮的高度 ,默认值:30。   wmode : 设置该项为transparent 可以使浏览按钮的flash背景文件透明,并且flash文件会被置为页面的最高层。 默认值:opaque 。   cancelImg :选择文件到文件队列中后的每一个文件上的关闭按钮图标 Uploadify还自带了很多参数及有用的方法和回调函数,都在API里,虽然是全英文的,但很容易看懂,这里就不说了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值