最近由于项目需要实现一个批量文件的上传功能,由于项目比较商业化,需要考虑到用户在上传过程中的用户体验效果。所以我们在上传的时候必须实现无刷新效果,当然上传文件通过Ajax是不能简单实现了。还好我们有另外一个比较靠普的方法,就是使用IFrame。
其实原理也很简单:
1.在一个Page上面放一个IFrame,并且将该IFrame的Css属性“display”设置为“none”,这样页面就不会有任何的变化。
2.将页面中的Form标记的属性target设置为IFrame的名称,并设置好它的Action属性。
<iframe id="asynciframe" name="asynciframe" style="display:none;"></iframe> <form id="form1" method="post" action="BlukResumeUpload.aspx" target="asynciframe" enctype="multipart/form-data" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> </asp:ScriptManager> <div id="msgSwitch" οnclick="showMsgBoard()"></div> <div class="controlPanel"> <input id="submit" type="submit" value="上传" οnclick="getTransactionState2()" /> <input id="btnAddUploadItem"type="button" value="添加上传项" οnclick="addUploadItem()" /> </div> <asp:HiddenField ID="hfTransactionId" runat="server" /> </form>
Demo
Html结构
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ResumeUpload.aspx.cs" Inherits="ResumeUpload.ResumeUpload" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" language="javascript" src="JS/jquery.js"></script>
<script type="text/javascript" language="javascript" src="JS/ajaxfileupload.js"></script>
<script language="javascript" type="text/javascript">
function ajaxFileUpload(controlId,uploadControl) {
$("#loading")
.ajaxStart(function () {
$(this).show();
})
.ajaxComplete(function () {
$(this).hide();
});
$.ajaxFileUpload
(
{
url: 'upload.ashx',
upControl:uploadControl,
secureuri: false,
fileElementId: controlId,
dataType: 'json',
success: function (data, status,uploadControl) {
//alert("completed!")
uploadControl.style.background = "url(Img/ok.gif) no-repeat right";
},
error: function (data, control, e) {
//alert("error!");
control.style.background = "url(Img/close.gif) no-repeat right";
}
}
)
return false;
}
function UploadFile() {
var uploadControls = $(".uploadControl");
var uploadControlsNum = $(".uploadControl").length;
for (var i = 0; i < uploadControlsNum; i++) {
if (uploadControls[i].value != "") {
ajaxFileUpload(uploadControls.get(i).id, uploadControls.get(i).parentNode); //,uploadControls.get(i).parentNode
//alert(document.getElementById("uploadContainer").innerHTML);
}
}
}
function AddUploadControl() {
var curUploadControlNum = $(".uploadControl").length+1;
var container = document.createElement("div");
var uploadControl = document.createElement("input");
uploadControl.setAttribute("id", "UploadControl" + curUploadControlNum.toString());
uploadControl.setAttribute("type", "file");
uploadControl.setAttribute("class", "uploadControl");
uploadControl.setAttribute("name", "UploadControl");
container.appendChild(uploadControl);
document.getElementById("uploadContainer").appendChild(container);
}
</script>
<style type="text/css">
#uploadContainer input
{
height:30px;
width:360px;
line-height:30px;
}
#uploadContainer div
{
width:400px;
/*background:url(Img/wait.gif) no-repeat right;*/
margin: 5px 0;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="uploadContainer">
<div>
<input id="UploadControl1" type="file" name="UploadControl" class="uploadControl" />
</div>
<div>
<input id="UploadControl2" type="file" name="UploadControl" class="uploadControl" />
</div>
</div>
<div>
<input type="button" value="添加上传选项" οnclick="AddUploadControl()" />
<input type="button" value="上传" οnclick="UploadFile()" />
</div>
</form>
</body>
</html>
后台代码
<%@ WebHandler Language="C#" Class="upload" %>
using System;
using System.Web;
using System.Web.Configuration;
using System.Text.RegularExpressions;
public class upload : IHttpHandler {
private string Js(string v) {//此函数进行js的转义替换的,防止字符串中输入了'后造成回调输出的js中字符串不闭合
if (v == null) return "";
return v.Replace("'", @"\'");
}
//下面就是一个简单的示例,保存上传的文件,如果要验证上传的后缀名,得自己写,还有写数据库什么的
public void ProcessRequest (HttpContext context) {
//System.Threading.Thread.Sleep(5000);
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
HttpServerUtility Server = context.Server;
//指定输出头和编码
Response.ContentType = "text/html";
Response.Charset = "utf-8";
HttpPostedFile f = Request.Files[0];
//获取上传的文件
string newFileName=Guid.NewGuid().ToString();//使用guid生成新文件名
if (f.FileName != "")
{
if (CheckFileType(System.IO.Path.GetExtension(f.FileName)))
{
try
{
f.SaveAs(Server.MapPath("~/Data/" + System.IO.Path.GetFileName(f.FileName)));
TODO 解析简历
}
catch (Exception ex)
{
throw ex;
}
}
else
{
}
}
}
public bool IsReusable {
get { return false; }
}
public bool CheckFileType(string fileName)
{
string allowFileType = WebConfigurationManager.AppSettings["allowFileType"];
return Regex.IsMatch(fileName, allowFileType);
}
}
老赵也实现了一个无刷新上次文件的组件,该组件的实现原理也是借助IFrame。不过该组件可以放在Asp.Net Ajax的核心控件UpdatePanel上使用,具体的例子就不介绍了,大家可以下载本博文附加的文件来查看该组件。
文件下载地址