iframe实现无刷新上传下载

来源:互联网 发布:ubuntu cacti 0.8.8h 编辑:程序博客网 时间:2024/06/03 16:48

        最近我维护的网站在审核时加了个上传下载的功能,能上传多个文件(文件很小、不超过3个、上传时可以多选、且要有上传进度),下载时有选择的下载。页面是用aspx做的,微软自带的只有单文件上传,于是乎想到flash。找了三个现成的,测试发现一个不兼容IE9,另两个都通过了,但发现有点山寨,flash是封装好的,一个上面有广告,一个是英文的,既是封装的,我也不知道里面到底干了什么,也没想去看As语言的语法。后来又找了个silverlight的,效果不错,但新的问题又有了,flash到时大多数电脑都装了的,但silverlight没装的人就多了去了,虽然给了下载的链接,但还是反映很差,时间又紧,无奈将功能裁减了点,上传时不显示实时进度,找了博客园上的cloudgamer写的仿163网盘的无刷新多文件上传系统自己稍微改了改就用上去了。下载找的这篇文章,用的是aspx的UpdatePanel。上传的效果如下:

 

        任务是完成了,但明显发现整合到我们项目中之后比较搓,我们项目用的Jquery,而这里是纯js(刚开始在IE9下还有Bug),我对js也不太熟悉,感觉这里还有些问题,于是花了点时间研究了里面的相关js语法,将基本的原理抽象出来,用Jquery写了个上传下载的例子,都是通过iframe实现的。

        先说上传:上传本质是通过提交自带的file控件,然后对a标签做了点处理,首先a标签做成图片的,a标签里面是file控件,然后每次选择文件后将这个file控件隐藏,新建一个file控件,这样就实现了点击一个图标上传多个文件。下面给出最基本的实现,至于实时显示选择的文件、已经上传的文件以及其他取消的功能就看各人的发挥了。

        下面贴出代码:Form窗体的代码

 <form id="uploadForm" action="FileUpLoad.ashx">    <table>        <tr>            <td>                <a href="javascript:void(0);" class="files" id="idFile"></a>            </td>            <td>                <input id="idBtnupload" type="button" value="开始上传" />            </td>        </tr>    </table></form>

        js的代码:

$(document).ready(function () {    //注册按钮的点击事件    $("#idBtnupload").click(btnUpLoad_onclick);    CreateFrame();    Init();})///创建iframefunction CreateFrame() {    var FrameName = "uploadFrame_" + Math.floor(Math.random() * 1000);    var oframe = $('<iframe name=' + FrameName + '>');    //修改样式是css,修改属性是attr    oframe.css("display", "none");    //在内部的前面加节点    $('body').prepend(oframe);    //设置form属性,关键是target要指向iframe    $("#uploadForm").attr("target", FrameName);    $("#uploadForm").attr("method", "post");    //注意ie的form没有enctype属性,要用encoding    $("#uploadForm").attr("encoding", "multipart/form-data");}///上传function btnUpLoad_onclick() {    $("#uploadForm").submit();}///初始化时新建一个file类型文本框function Init() {    var fileJquery = $("<input type='file'>").attr("name", "Test").attr("title", "Jquery");    //这是运用js的onchange属性赋值的(不知道用Jquery怎么实现,用Jquery绑定方法没能实现)    fileJquery[0].onchange = function () { return OperateAndNew(fileJquery[0]); };    fileJquery.appendTo("#idFile");}///每当添加一个附件时执行function OperateAndNew(o) {    if (o.value != "") {        o.style.display = "none"        Init();    }}///上传完成后提示消息function Finish(msg) {    alert(msg);}

        后台处理程序的代码:

using System.Web;using System.IO;namespace UpLoadAndDown1021.上传文件{    /// <summary>    /// FileUpLoad 的摘要说明    /// </summary>    public class FileUpLoad : IHttpHandler    {        public void ProcessRequest(HttpContext context)        {            int iTotal = context.Request.Files.Count;            for (int i = 0; i < iTotal; i++)            {                HttpPostedFile file = context.Request.Files[i];                if (file.ContentLength > 0 || !string.IsNullOrEmpty(file.FileName))                {                    //保存文件                    file.SaveAs(System.Web.HttpContext.Current.Server.MapPath("./UpLoadFile/" + Path.GetFileName(file.FileName)));                }            }            context.Response.Write("<script>window.parent.Finish('上传文件成功!');</script>");        }        public bool IsReusable        {            get            {                return false;            }        }    }}

        其次是下载:一开始用的a标签,直接点击下载,后来发现文本或者图片的话就不行,会直接在浏览器中打开;后来用Ajax异步调用时,但总有问题,我希望直接通知浏览器下载,而不是返回前台;于是也用iframe实现,本质上就是创建了一个iframe,然后将其指向下载的方法。

        前台Form的代码:

    <form id="idForm" action="">    下载文件:<input type="text" id="AnnexName" value="绝密资料共享.txt" />    <br />    文件全路径:<input type="text" style="width: 500px" id="FullName" value="D:\pfeEXE\UpLoadAndDown1021\Demo.DownLoad\TestFile\绝密资料.txt" />    <br />    <input type="button" id="btnDownLoad" name="Test" value="DownLoad" />    </form>

        js代码:

$(document).ready(function () {    $("#btnDownLoad").click(btnDownLoad_onclick);})function CreateFrame() {    var AnnexName = $("#AnnexName").val();    var FullName = $("#FullName").val();    var FrameName = "uploadFrame_" + Math.floor(Math.random() * 1000);    var oframe = $('<iframe name=' + FrameName + '>');    //修改样式是css,修改属性是attr    oframe.css("display", "none");    oframe.attr("src", "DownLoad.aspx?opType=" + "DownLoadAnnex" + "&AnnexName=" + AnnexName + "&FullName=" + FullName);    //在内部的前面加节点    $('body').prepend(oframe);}function btnDownLoad_onclick() {    CreateFrame();}

        后台处理程序的代码:

using System;using System.IO;namespace UpLoadAndDown1021.Demo.DownLoad{    public partial class DownLoad : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            if (Request.QueryString["opType"] == "DownLoadAnnex")            {                ///完整路径名(包括文件名)                string fulleName = Request["FullName"];                ///下载保存的文件名                string dispalyName = Request["AnnexName"];                DownLoadFile(fulleName, dispalyName);            }        }        /// <summary>        /// 下载文件        /// </summary>        /// <param name="FullName">待下载的全路径</param>        /// <param name="DisPalyName">显示的名称</param>        private void DownLoadFile(string FullName, string DisPalyName)        {            if (File.Exists(FullName))            {                FileInfo file = new FileInfo(FullName);                Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8"); //解决中文乱码                Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(DisPalyName)); //解决中文文件名乱码                    Response.AddHeader("Content-length", file.Length.ToString());                Response.ContentType = "appliction/octet-stream";                Response.WriteFile(file.FullName);                Response.End();            }            else            {                //可以提示文件不存在或已丢失            }        }    }}

        至此完成,只是思想,实现的业务还很少,其他还有实时文件上传状态、进度等。项目源代码。欢迎阅读、讨论、转载,转载请保留原文地址。





原创粉丝点击