现在位置首页 / 前端开发 /正文

Jquery 下载插件jDownload--弹出框提示文件信息及下载(支持asp.net)---代码

作者: IT小兵 | 2014年3月26日| 热度:℃ | 评论: |参与:

在上一篇文章中,介绍了一个jquery的下载插件jDownload[Jquery 下载插件jDownload--弹出框提示文件信息及下载(支持asp.net)]。

由于下载文件是需要服务端支持的,jDownload默认是支持php(官方代码就是php)。

我除了汉化一下代码,还将服务端从php换成asp.net的ashx的一般处理程序。

提供给各位.net开发人员使用。

预览地址:http://www.suchso.com/code/jsdownload/HtmlPage.html

没有部署成虚拟目录,文件下载有问题。

jDownload插件的代码非常简单。主要是调用Jquery ui的主题,弹出对话框,

在对话框中,动态添加一个iframe,使用iframe进行文件的下载。

初始化:

var _this = $(this);
dialog.html("");
// if filePath is not specified then use the href attribute
var filePath = (settings.filePath == null) ? 
$(this).attr('href') : settings.filePath;
dialog.html('<p>正在获取文件信息...</p><img src="' 
+ settings.root + 'js/loader.gif" alt="正在获取文件信息" />');
$.ajax({
type : 'get',
url  : settings.root+'/FileDown.ashx',
data : 'action=find&path='+filePath,
error: function (XMLHttpRequest, textStatus, errorThrown) {
debugger
dialog.html("<p class=\"jDownloadError\">失败.</p>");
},
success : function(data) {
setTimeout(function() {
if(data == "error") {
dialog.html("<p class=\"jDownloadError\">文件未找到.</p>");
} else {
if(settings.showfileInfo == true) {
var url = settings.root + 'FileDown.ashx?action=info&path=' + filePath;
// get file information
$.getJSON(url, function(data) {
// Check to see if file is not allowed
if(data.error == 'denied'){
// append new file info
dialog.html('<p class=\"jDownloadError\">该文件类型不允许下载.</p>');
}else{
// parse JSON
var html  = "<div class=\"jDownloadInfo\">";
html += "<p><span>文件名称:</span> "+data.filename+"</p>";
html += "<p><span>文件类系:</span> "+data.filetype+"</p>";
html += "<p><span>文件大小:</span> "+data.filesize+" KB</p>";
html += "</div>";
// remove any old file info & error messages
var desc = "";
$('.jDownloadInfo, .jDownloadError').remove();
if (_this.attr('title') !== null && _this.attr('title') != "undefined") {
desc = "点击立即下载";
}
else {
desc = (_this.attr('title').length > 0) 
? _this.attr('title') : '点击立即下载';
}
// append new file info
dialog.html('<p>'+desc+'</p>'+html);
}
});
}
}
}, 10);
}
});

在初始化的时候,用ajax调用服务端方法,判断文件是否存在,存在的话再次调用服务获取文件名称 大小等信息。

点击立即下载,则是将动态生成的iframe 设置一下src,则会开始下载。

/* Iniate download when value Ok is iniated via the dialog */
		function start_download(i){
			// change iframe src to fieDownload.php with filePath as query string?? 
			iframe.attr('src', settings.root+'/FileDown.ashx?action=download&path='+dialog.data('jDownloadData').filePath);
			// Close dialog
		//	dialog.dialog('close');
			return false;
		}		

asp.net服务端方法:

服务端我是采用了ashx一般处理程序。提供一个函数进行文件的判断和返回文件下载。

通过2个参数:action和path即可完成下载功能。

     下载文件,支持大文件、续传、速度限制。支持续传的响应头Accept-Ranges、ETag,请求头Range 。

     Accept-Ranges:响应头,向客户端指明,此进程支持可恢复下载.实现后台智能传输服务(BITS),值为:bytes;

     ETag:响应头,用于对客户端的初始(200)响应,以及来自客户端的恢复请求,

     必须为每个文件提供一个唯一的ETag值(可由文件名和文件最后被修改的日期组成),

这使客户端软件能够验证它们已经下载的字节块是否仍然是最新的。

     Range:续传的起始位置,即已经下载到客户端的字节数,值如:bytes=1474560- 。

     另外:UrlEncode编码后会把文件名中的空格转换中+(+转换为%2b),

但是浏览器是不能理解加号为空格的,所以在浏览器下载得到的文件,空格就变成了加号;

     解决办法:UrlEncode 之后, 将 "+" 替换成 "%20",因为浏览器将%20转换为空格


文件判断是否存在及文件大小信息返回的部分代码:

  filePath = httpContext.Server.MapPath(filePath);
            if (!File.Exists(filePath))
            {
                httpContext.Response.StatusCode = 404;
                if (isshowinfo == "find")
                {  
                     ReturnResponse(httpContext, "error");
                 }
                return false;
            }
            else
            {
                if (isshowinfo == "find")
                {
                    ReturnResponse(httpContext, "ok");
                }  
            }
            #endregion
            #region 定义局部变量#region 定义局部变量
            long startBytes = 0;
            long stopBytes = 0;
            int packSize = 1024 * 10; //分块读取,每块10K bytes
            string fileName = Path.GetFileName(filePath);
            FileInfo fileinfo = new FileInfo(filePath);
            string json = "{\"filename\":\"" + fileinfo.Name
             + "\",\"filetype\":\"" + fileinfo.Extension
              + "\",\"filesize\":\"" + fileinfo.Length + "\"}";
         
            switch (isshowinfo)
            {
               
                case "info": //action
                    ReturnResponse(httpContext, json);
                    break;
            }

文件信息返回采用json串:例子:

{

    "filename": "as.pdf",

    "filetype": ".pdf",

    "filesize": "206109"

}

asp.net文件下载代码:

FileStream myFile = new FileStream(filePath,
         FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
BinaryReader br = new BinaryReader(myFile);
long fileLength = myFile.Length;
int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);
//毫秒数:读取下一数据块的时间间隔
string lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;
//便于恢复下载时提取请求头;
#endregion
#region --验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修改过
if (myFile.Length > long.MaxValue)
{//-------文件太大了-------
httpContext.Response.StatusCode = 413;//请求实体太大
return false;
}
if (httpContext.Request.Headers["If-Range"] != null)
//对应响应头ETag:文件名+文件最后修改时间
{
//----------上次被请求的日期之后被修改过--------------
if (httpContext.Request.Headers["If-Range"].Replace("\"", "") != eTag)
{//文件修改过
httpContext.Response.StatusCode = 412;//预处理失败
return false;
}
}
#endregion
try
{
#region -------添加重要响应头、解析请求头、相关验证
httpContext.Response.Clear();
if (httpContext.Request.Headers["Range"] != null)
{//------如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数------
httpContext.Response.StatusCode = 206;//重要:续传必须,表示局部范围响应。初始下载时默认为200
string[] range = httpContext.Request.Headers["Range"].Split(new char[] { '=', '-' });//"bytes=1474560-"
startBytes = Convert.ToInt64(range[1]);//已经下载的字节数,即本次下载的开始位置  
if (startBytes < 0 || startBytes >= fileLength)
{//无效的起始位置
return false;
}
if (range.Length == 3)
{
stopBytes = Convert.ToInt64(range[2]);//结束下载的字节数,即本次下载的结束位置  
if (startBytes < 0 || startBytes >= fileLength)
{
return false;
}
}
}
httpContext.Response.Buffer = false;
//httpContext.Response.AddHeader("Content-MD5", My_Des.MD5JiaMi_File(filePath));//用于验证文件
httpContext.Response.AddHeader("Accept-Ranges", "bytes");//重要:续传必须
httpContext.Response.AppendHeader("ETag", "\"" + eTag + "\"");//重要:续传必须
httpContext.Response.AppendHeader("Last-Modified", lastUpdateTiemStr);//把最后修改日期写入响应                
httpContext.Response.ContentType = "application/octet-stream";//MIME类型:匹配任意文件类型
httpContext.Response.AddHeader("Content-Disposition", 
"attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20"));
httpContext.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
httpContext.Response.AddHeader("Connection", "Keep-Alive");
httpContext.Response.ContentEncoding = Encoding.UTF8;
if (startBytes > 0)
{//------如果是续传请求,告诉客户端本次的开始字节数,
//总长度,以便客户端将续传数据追加到startBytes位置后----------
httpContext.Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", 
startBytes, fileLength - 1, fileLength));
}
#endregion
#region -------向客户端发送数据块-------------------
br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
int maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize);
//分块下载,剩余部分可分成的块数
for (int i = 0; i < maxCount && httpContext.Response.IsClientConnected; i++)
{//客户端中断连接,则暂停
httpContext.Response.BinaryWrite(br.ReadBytes(packSize));
httpContext.Response.Flush();
if (sleep > 1) System.Threading.Thread.Sleep(sleep);
}
#endregion
}
catch
{
ret = false;
}
finally
{
br.Close();
myFile.Close();
}

项目的部分代码就是这样。如果要运行查看效果,请下载demo代码:

百度网盘下载:http://pan.baidu.com/s/1hqkOrTM


转发注明:IT分享  http://www.suchso.com 


点击阅读本文所属分类的更多文章: 前端开发 。和高手一起交流:346717337
友荐云推荐

未注明转发、原文均为本站原创。分享本文请注明 原文链接

给您更多信息和帮助

在这里您可以找到更多:

技术交流群:346717337 Jquery插件交流

投稿:suchso@vip.qq.com

承接:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/业务咨询

抢天猫双11红包
推荐使用阿里云服务器
echarts教程系列
本月最热文章

微信扫一扫,徜徉悠嘻网,您的休闲乐园

微信公众号:快乐每一天

随机文章
标签

技术交流群:346717337

投稿:suchso@vip.qq.com

专业专注:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/付费问题咨询