在工作中,设计多个符合条件的文件一起上传到服务器的需求.两个版本采用了两种不同的机制.先备下来:
第一种方案:采用异步机制,同AJAX的机制一样.xmlhttp=new XMLHttpRequest();
1:JS创建一些组件,包括文件操作组件Scripting.FileSystemObject,建立ADODB.Stream对象(MDAC微软数据库访问组件),XMLHttp组件.
var stream=null;
//创建FileSystemObject
try
{
fso = new ActiveXObject("Scripting.FileSystemObject");
}
catch(e)
{
if(confirm("您的IE未加载某种Windows组件,请按“确认”自动加载,否则批量上传照片会失败。\n"))
{
try{
var wsh = new ActiveXObject('WScript.Shell');
if (wsh)
wsh.Run('regsvr32 Scrrun.dll');
return true;
}
catch(ee)
{
alert("然后请按照页面说明,完成“IE设置”的操作,将此站点设为“可信任站点”。");
return false;
}
}
return false;
}
//创建Ado.Stream
try
{
stream=new ActiveXObject("ADODB.Stream");
}
catch(e)
{
alert("请到页面中下载安装msado控件.rar");
return false;
}
//创建XML2.0
try{
xmldoc = new ActiveXObject("MSXML2.DOMDocument");
}
catch(ew){
alert("请下载安装MSXML2.0");
return false;
}
try {xmlhttp=new XMLHttpRequest();}
catch (e)
{try
{xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");}
catch (e)
{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
}
}
2.接着就是选择文件,通过上传控件获取文件夹里的任何一个文件的文件名称,获取这个文件名所在的文件夹地址P.判断P+文件名是否是符合要求的
{
txtphotofiles.options[txtphotofiles.length] = new Option(oRow["KS_BMH"].toString()+"|"+SelPhotoPath+oRow["KS_SFZ"].toString()+".jpg");
}
3.关键代码:将文件通过XML的形式来上传到后台,首先要将文件转换为XML数据流,下面为返回的函数
{
var sTmp="";
stream.Mode=3;
stream.Type = 2;
stream.Charset="ascii";
stream.Open();
stream.LoadFromFile(sFileName);
sTmp = stream.ReadText(-1);
stream.Close();
return sTmp;
}
4.将文件的XML值放到XMLDOCUMENT中,上传:(可以通过JS将文件的XML值传到Web服务,或ASHX或ASPX后台来处理)
if(document.getElementById("listPhotoFiles").options[0]!=null)
{
var sFileName =document.getElementById("listPhotoFiles").options[0].innerText;
var filename=sFileName.split('|');
var sXmlData=GetXmlData(filename[1].toString());
//形成XML数据流
xmldoc.loadXML('<?xml version="1.0" encoding="utf-8"?> <root/>');
xmldoc.documentElement.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes");
var node = xmldoc.createElement("file");
//将数据流类型设置为bin.base64
node.dataType = "bin.base64";
node.nodeTypedValue =sXmlData;
//将文件数据流加入到XML结点
xmldoc.documentElement.appendChild(node);
//可以将进度条显示出来(以下两条代码)
document.getElementById("in").style.width=Math.ceil((nIndex+1)*100/list)+"%";
document.getElementById("in").innerHTML=Math.ceil((nIndex+1)*100/list)+"%";
//下面一句是传到Web服务处理using System.Web.Script.Services;[ScriptService]
WSUploadPhotos.UploadPhoto(xmldoc.xml,GetUploadResult); //GetUploadResult(obj)为异步的返回函数名称,自己任意定义
//var don=document.domain;
//以下两段是传到AspxUpPhotos.aspx处理
//xmlhttp.open("GET","AspxUpPhotos.aspx?XML=" + xmldoc.xml+"&filename0=" + filename[0].toString(),false);
//xmlhttp.send();
document.getElementById("listPhotoFiles").options[0] = null;
nIndex++;
}
5.后台接收数据,保存文件
Web服务版:
XmlDocument oXmlDoc = new XmlDocument();
oXmlDoc.LoadXml(XML字符串); 就是JS里的xmldoc.xml
XmlNode xn = oXmlDoc.SelectSingleNode("root/file");
byte[] fileContent = Convert.FromBase64String(xn.InnerText);
FileStream oStream = new FileStream(文件名, FileMode.OpenOrCreate, FileAccess.Write); //如果要覆盖,保证此文件不是只读的
oStream.Write(fileContent, 0, fileContent.Length);
oStream.Close();
总结:此方案主要是XML和ADODB.Stream对象的使用.但是对电脑的IE设置有要求,文件控件要有,ADODB.Stream对象要有,没有的话,可以去下载一个MDAC_TYP.exe安装并注册了.但是有点查毒软件会认为这个是病毒,写一个TEXT文本,内容为:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{00000566-0000-0010-8000-00AA006D2EA4}]
"Compatibility Flags"=dword:0
将此扩展名改为:reg
一般来讲,反正我在用的时候,就出现了异常,报错:不能跨域访问.解决的办法就是到IE工具的选项里的"允许跨域访问"钩选了.
第二种方案:使用JQuery格式的一个JS控件,名称为jquery.uploadify.js,网上可以下载到.并且有它的使用说明.
$(function() {
if (version == -1) {
$("#divdownflash").show();
$("table").hide();
alert("您电脑环境中缺少Flash,请安装 flash player!否则不能上传!");
}
else{
$("#fileUpload").fileUpload({
'uploader': '../Images/uploader.swf', //所下载的组件包里含有这个文件,这里是这个图片的位置
'type': 'POST',
'cancelImg': '../Images/cancel.png', //取消按钮的图片
'script': '../Ashx/LoadStudents.ashx?t=' + D,
'folder': 'StudentPhoto', //文件位置
'multi': true, //设置为可以多选
'fileDesc': 'jpg文件', //扩展名
'fileExt': '*.jpg;*.JPG;*.jpeg;*JPEG',
'buttonText': 'Select Files', //浏览按钮的名称,可惜不支持中文呀
'displayData': 'speed',
'queueSizeLimit': '1',
'buttonImg': '../Images/AddPhoto.gif', //添加按钮的图片
'onSelect': function(event, queueID, fileObj) { //每一个选择的文件
$("#pp").html("在此显示可被上传的照片列表: 正在捕捉有效照片,请稍等......<img src='../images/spinner3-greenie.gif'/>");
//$("#divload").show();
//timer("document.getElementById('pp').innerHtml='在此显示可被上传的照片列表: 正在捕捉有效照片,请稍等......';", 1000); 也许是因为异步上传的速度太快,这些文字,我始终显示不出来,郁闷
if (stus.indexOf("," + fn + ",") == -1) {
return false; //如果不想要这个图片,return false就可以了.
}
else {
//可以在这里做些统计 }
},
'onQueueFull': function(a, b) { //.....
},
'onSelectOnce': function(event, data) { //多选文件后的最后一步,自己定义哦
//$("#divload").hide();
$("#pp").html("在此显示可被上传的照片列表: 捕捉完毕!");
chlikNum = data.fileCount;
var upnum = 0;
upnum = yesFile.split(',').length - 2;
alert("您共累计选过 " + chlikNum + " 张照片(在上传操作之前)");
if (selNum == false) alert("没有任何的 可上传文件!");
},
'onClearQueue': function(event, data) { //...
},
'onComplete': function(event, queueID, fileObj, response, data) { //实在的上传了一个文件后
var restr = response.toString();
if (restr.substring(0, 1) == "S" || restr.substring(0, 1) == "H") { noNum++; noti_fail += restr.substring(1, restr.length) + " "; }
else if (restr.substring(0, 1) == "Y") { yesNum++; noti_pass += restr.substring(1, restr.length) + " "; }
},
'onAllComplete': function(event, data) { //等全部文件都上传完毕后
if (selNum == true)
alert("操作完毕!");
else
alert("无 文件上传!");
if (noNum == 0)
noti_fail += " 无";
if (yesNum == 0)
noti_pass += " 无";
$("#divMsg").html("共有" + chlikNum + " 张被您选择!<br/> 其中,捕捉成功的有效照片" + (Number(yesNum) + Number(noNum)) + "张,<br/>" + yesNum + "张成功上传," + noNum + "照片不符合要求!<br/>" + noti_pass + noti_fail + "<br/>" + btnhtml);
yesNum = 0;
noNum = 0;
chlikNum = 0;
$("#divBrown table").hide();
$("#divMsg").show();
}
});
}
这里,我只是用了必须的一些.要求IE有FLASH10(至少),还有很多的操作,不过网上的知道一般都是英文的.我研究了一段时间呢.最后实现了多选,一次上传.
接着,到了后台ashx的处理关键代码:HttpPostedFile hpf = context.Request.Files["Filedata"];这下好了,hpf可以完成所有的任务,获取文件名,保存.SaveAs等方法.任意保存,任意处理照片...
以上两个解决方案就是我的揣摩结果,以后也许还有续集吧....祝我好运!