文件的异步上传
最近由于项目需要实现一个批量文件的上传功能,由于项目比较商业化,需要考虑到用户在上传过程中的用户体验效果。所以我们在上传的时候必须实现无刷新效果,当然上传文件通过Ajax是不能简单实现了。还好我们有另外一个比较靠普的方法,就是使用IFrame。
其实原理也很简单:
DemoHtml结构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" onclick="showMsgBoard()"></div> <div class="controlPanel"> <input id="submit" type="submit" value="上传" onclick="getTransactionState2()" /> <input id="btnAddUploadItem"type="button" value="添加上传项" onclick="addUploadItem()" /> </div> <asp:HiddenField ID="hfTransactionId" runat="server" /> </form>
<%@ 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="添加上传选项" onclick="AddUploadControl()" /> <input type="button" value="上传" onclick="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上使用,具体的例子就不介绍了,大家可以下载本博文附加的文件来查看该组件。
文件下载地址