采用AJAX实现带进度条的文件上传(C#)
客户端upload.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>水月AJAX文件上传</title>
<script language="javascript" src="upload.js"></script>
</head>
<body>
<form id="form1" method="post" enctype="multipart/form-data" name="form1">
<table width="500" border="1" cellpadding="1" cellspacing="0" bordercolorlight="#666666" bordercolordark="#FFFFFF" bgcolor="#D4D0C8">
<tr valign="top" id="control">
<td height="42" valign="middle"><input type="file" name="UpFileControl" id="UpFileControl" style="100%">
<div id="FinalBar" style="color:#FF0000"></div> </td>
<td width="1" height="40" valign="middle"><input name="btn_send" type="button" id="btn_send" value="上传" onClick="BeginSend()" style="height:100%"></td>
</tr>
<tr valign="top" id="bar" style="display:none">
<td height="42">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr style="font-size:12px">
<td id="filename"> </td>
<td id="speed" align="right"> </td>
</tr>
</table>
<div style="position:absolute; height:19px; z-index:101; 448px;">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="19" align="center" valign="bottom" id="perent" style="font-size:16px"> </td>
</tr>
</table>
</div>
<table width="100%" height="19" border="1" align="center" cellpadding="0" cellspacing="0" bordercolorlight="#666666" bordercolordark="#FFFFFF" bgcolor="#FFFFFF" rules="rows">
<tr>
<td height="10" bgcolor="#99CCFF" id="perentBar" style="0%"></td>
<td height="10"></td>
</tr>
</table></td>
<td valign="bottom"><input name="btn_cancel" type="button" id="btn_cancel" value="中断" onClick="CancelSend()" style="height:100%"></td>
</tr>
<tr>
<td width="99%" height="1">
<select name="select_uploaded_file" size="4" multiple id="select_uploaded_file" style="100%;"></select>
</td>
<td valign="bottom">
<input name="uploaded_file" type="hidden" id="uploaded_file">
<input name="Btn_del_selected_uploaded" type="button" id="Btn_del_selected_uploaded" onClick="del_selected_uploaded()" value="删除" style="height:100%">
</td>
</tr>
</table>
</form>
</body>
</html>
upload.js脚本
var xml_http,ado_stream,mFilename;
var SendBlockCount,SendCount,BlockSize,Breaked;
var lastSendTime,maxFileLimit;
var submited = false;
BlockSize = 1024 * 128;
maxFileLimit = 1024 * 1024 * 100;
function BeginSend()
{
if(document.getElementById("UpFileControl") && document.getElementById("UpFileControl").value.length > 0)
{
document.getElementById("speed").innerHTML = "0 KB/Sec";
document.getElementById("perent").innerHTML = "0%";
document.getElementById("perentBar").style.width = "0%";
document.getElementById("bar").style.display = "block";
document.getElementById("control").style.display = "none";
var _filename = document.getElementById("UpFileControl").value;
document.getElementById("filename").innerHTML = _filename.substring(_filename.lastIndexOf("\\") + 1,_filename.length);
setTimeout("SendFile()",1);
}
else
{
return;
}
}
function SendFile()
{
Breaked = false;
ado_stream = new ActiveXObject("ADODB.Stream");
ado_stream.Type = 1;
ado_stream.Open();
try
{
ado_stream.LoadFromFile(document.getElementById("UpFileControl").value);
}
catch(ex)
{
alert("Error:" + ex.description +"\n无法打开文件 "+document.getElementById("UpFileControl").value+",传输已终止!");
OverSend();
return;
}
ado_stream.position = 0;
if(ado_stream.size == 0)
{
alert("不能上传空文件");
OverSend();
return;
}
if(ado_stream.size > maxFileLimit)
{
alert("文件过大");
OverSend();
return;
}
SendCount = Math.ceil(ado_stream.size / BlockSize);
var UpFile = document.getElementById("UpFileControl").value;
mFilename = UpFile.substring(UpFile.lastIndexOf("\\") + 1,UpFile.length);
SendBlockCount = 0;
lastSendTime = new Date();
xml_http = new ActiveXObject("Microsoft.XMLHTTP");
SendData();
return;
}
function SendData()
{
if(!Breaked)
{
xml_http.open("POST","UpLoad.aspx?fn="+escape(mFilename)+"&ps="+SendBlockCount,true);
xml_http.onreadystatechange = ShowPerent;
xml_http.send(ado_stream.Read(BlockSize));
}
}
function ShowPerent()
{
if(xml_http.readystate == 4 && xml_http.status == 200)
{
if(SendBlockCount == 0)
{
mFilename = xml_http.responseXML.selectSingleNode("//*").text;
}
SendBlockCount++;
var now = new Date();
var perentStat = Math.floor(SendBlockCount/SendCount * 100);
perentStat += "%"
var sendSpeed = BlockSize * SendBlockCount / (now.getTime() - lastSendTime.getTime()) * 1000;
if(sendSpeed != "Infinity")
{
if(sendSpeed < 1000)
sendSpeed = Math.floor(sendSpeed) + " ";
else
{
sendSpeed = Math.floor(sendSpeed/1024) + " K";
}
}
else
{
sendSpeed = "0 ";
}
document.getElementById("speed").innerHTML = sendSpeed + "B/Sec";
document.getElementById("perent").innerHTML = perentStat;
document.getElementById("perentBar").style.width = perentStat;
if(SendBlockCount < SendCount)
{
SendData();
}
else
{
var SavedFileName = mFilename.substring(mFilename.lastIndexOf("\\")+1,mFilename.length);
var upLoadedFileSelect = document.getElementById("select_uploaded_file");
upLoadedFileSelect.add(new Option(SavedFileName,mFilename));
update_uploaded_file_str();
OverSend();
}
}
}
function CancelSend()
{
Breaked = true;
xml_http.abort();
delete_single_file(mFilename);
OverSend();
}
function OverSend()
{
document.getElementById("bar").style.display = "none";
document.getElementById("control").style.display = "block";
var oTextRange = document.body.createTextRange();
oTextRange.moveToElementText( document.getElementById("UpFileControl") ) ;
oTextRange.execCommand( 'Cut' ) ;
oTextRange.execCommand( 'Paste' ) ;
ado_stream.Close();
}
function delete_all_file()
{
var uploaded_file_str = document.getElementById("uploaded_file");
var FilesStr = uploaded_file_str.value;
if(!Breaked)
{
Breaked = true;
xml_http.abort();
if(FilesStr != "")
FilesStr += "\n" + mFilename;
}
if(FilesStr != "")
delete_single_file(FilesStr);
}
function del_selected_uploaded()
{
var upLoadedFileSelect = document.getElementById("select_uploaded_file");
var FilesStr = "";
for(var i=upLoadedFileSelect.length - 1;i >= 0;i--)
{
if(upLoadedFileSelect.options[i].selected)
{
if(FilesStr != "")
FilesStr += "\n";
FilesStr += upLoadedFileSelect.options[i].value;
upLoadedFileSelect.remove(i);
}
}
if(FilesStr != "")
delete_single_file(FilesStr);
update_uploaded_file_str();
}
function delete_single_file(mfns)
{
var param = "fns=" + escape(mfns);
var xml_http2 = new ActiveXObject("Microsoft.XMLHTTP");
xml_http2.open("POST","UpLoad.aspx?fn=&ps=-1",true);
xml_http2.setRequestHeader("content-type","application/x-www-form-urlencoded");
xml_http2.setRequestHeader("Content-Length",param.length);
xml_http2.send(param);
}
function update_uploaded_file_str()
{
var upLoadedFileSelect = document.getElementById("select_uploaded_file");
var uploaded_file_str = document.getElementById("uploaded_file");
var fileListStr = "";
for(var i = 0;i < upLoadedFileSelect.length;i++)
{
if(i != 0)
fileListStr += "\n";
fileListStr += upLoadedFileSelect.options[i].value;
}
uploaded_file_str.value = fileListStr.replace(/\\/gi,"/");
}
function WindowUnload_Event()
{
if(!submited)
delete_all_file();
else if(!Breaked)
{
CancelSend();
}
}
window.onbeforeunload = WindowUnload_Event;
服务器端upload.aspx源代码:
using System;
using System.Xml;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Configuration;
namespace UpLoad
{
public class XMLHttp : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
string partid = Request.QueryString["ps"];
string filename = Request.QueryString["fn"];
string upPath = System.Configuration.ConfigurationSettings.AppSettings["upLoadFilePath"].ToString(); //文件保存路径,请自行设置。请确保具备该路径的访问权限。
if(!upPath.EndsWith("\\"))
upPath += "\\";
if(partid == "-1")
{
string[] filenames = Request.Form["fns"].Split('\n');
for(int i=0;i < filenames.Length;i++)
{
if(System.IO.File.Exists(upPath + filenames[i]))
System.IO.File.Delete(upPath + filenames[i]);
}
return;
}
if(partid == "0")
{
DateTime myDate = DateTime.Now;
string _vPath = myDate.Date.ToString("yyyy-MM-dd").Replace("-","\\") + "\\";
if(!System.IO.Directory.Exists(upPath+_vPath))
System.IO.Directory.CreateDirectory(upPath+_vPath);
string Ext = System.IO.Path.GetExtension(filename);
filename = _vPath + filename;
int fn_len = filename.Length - Ext.Length;
int i = 0;
while(System.IO.File.Exists(upPath + filename))
{
i++;
filename = filename.Substring(0,fn_len) + String.Format("({0})",i.ToString()) + Ext;
}
}
byte[] buffer = Request.BinaryRead(Convert.ToInt32(Request.ContentLength));
System.IO.FileStream FS = new System.IO.FileStream(upPath + filename,System.IO.FileMode.Append);
FS.Write(buffer,0,buffer.Length);
FS.Close();
Response.Clear();
Response.ContentType = "text/xml";
Response.Write(@"");
Response.Write("
Response.End();
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
}
}
说明:本上传功能使用了Adodb.stream组件,由于该组件的安全行问题,部分可能无法创建对象,请手动修改注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{00000566-0000-0010-8000-00AA006D2EA4}
将Compatibility Flags改为0
并将页面地址添加到受信任站点,并降低受信任站点的安全特性