iframe实现无刷新上传下载

        最近我维护的网站在审核时加了个上传下载的功能,能上传多个文件(文件很小、不超过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();
})
///创建iframe
function 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
            {
                //可以提示文件不存在或已丢失
            }
        }
    }
}

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





  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值