最近某客户对一个系统的附件上传提出异议,要求上传大附件,同时可提供上传进度条,在同事的帮助下,验证了jquery.plupload框架。
图片效果:
具体代码结构:
具体步骤:
1、Scripts上传相关的脚本
2、新建aspx文件
具体代码如下:
<link rel="stylesheet"href="Scripts/jquery.plupload.js/jquery.ui.plupload/css/jquery.ui.plupload.css"type="text/css" />
<link rel="stylesheet"href="Scripts/jquery.plupload.js/jquery-ui.css"type="text/css" />
<scriptsrc="Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<scriptsrc="Scripts/jquery-ui-1.9.1.custom.min.js"type="text/javascript" ></script>
<scriptsrc="Scripts/jquery.plupload.js/browserplus-min.js"type="text/javascript"></script>
<scriptsrc="Scripts/jquery.plupload.js/plupload.full.js"type="text/javascript" ></script>
<scriptsrc="Scripts/jquery.plupload.js/i18n/zh-cn.js"type="text/javascript" ></script>
<script src="Scripts/jquery.plupload.js/jquery.ui.plupload/jquery.ui.plupload.js"type="text/javascript" ></script>
<scripttype="text/javascript">
$(function (){
$("#uploader").plupload({
runtimes: 'gears,flash,silverlight,browserplus,html5',
url: 'UploadHandler.ashx', //Post地址
max_file_size: '200mb', // 文件上传最大限制。
chunk_size: '2mb', // 上传分块每块的大小,这个值小于服务器最大上传限制的值即可。
unique_names: false, // 上传的文件名是否唯一
multiple_queues: true, //多文件
// 是否生成缩略图(仅对图片文件有效)
resize: { width: 320, height: 240, quality: 90 },
// 这个数组是选择器,就是上传文件时限制的上传文件类型
filters: [
{ title: "Image files", extensions:"jpg,gif,png" },
{ title: "Zip files", extensions:"zip,rar,7z" }
],
urlstream_upload: true,
flash_swf_url: 'Scripts/jquery.plupload.js/plupload.flash.swf',
silverlight_xap_url:'Scripts/jquery.plupload.js/plupload.silverlight.xap',
init: {
FileUploaded: function (up, file, info) {
if (info.response) {
InitInput(info.response, file);
}
//$("#uploadfile").val($("#uploadfile").val() +info.response + "|");
},
Error: function (up, args) {
//发生错误
if (args.file) {
alert(args.filepath);
//alert('[error] File:'+ args.file);
} else {
alert('[error]' +args);
}
}
}
});
function InitInput(str, file) {
var obj = eval("(" + str + ")"); //转换为json对象
if (obj.status == "0") {
$("#uploadFileNormal").val("false");
alert("文件名包涵特殊字符: " + obj.msg + " 请重新上传!");
} else {
var divuploadfile = $("#divuploadfile");
var strs = str.split(":");
var strinput = "<inputtype=\"hidden\" id=\"" + strs[0] + "_" + file.id+ "\" name=\"uploadfiles\" value=\"" + obj.msg +"\"> ";
divuploadfile.append(strinput);
$("#uploadFileNormal").val("true");
}
}
// 这一块主要是防止在上传未结束前进行提交
$('webform').submit(function (e) {
var uploader = $('#uploader').pluploadQueue(); // 取得上传队列
if (uploader.files.length > 0) {
uploader.bind('StateChanged', function () {
if (uploader.files.length ===(uploader.total.uploaded + uploader.total.failed)) {
$('form')[0].submit();
}
});
uploader.start();
} else
alert('You must at least upload one file.');
return false;
});
});
</script>
</head>
<body>
<formid="webform" runat="server">
<div>
<div>
<input id="uploadFileNormal"type="hidden" name="name" value="true" />
<div id="divuploadfile"style="display: none;">
<input type="hidden"name="uploadfile" id="uploadfile" /></div>
<!--======================================================-->
<div>
<div >
<h2>一次选择多个文件进行上传</h2>
</div>
<div id="uploader"style="width: 600px">
<p>您的浏览器未安装 Flash, Silverlight, Gears, BrowserPlus 或者支持HTML5 .</p>
</div>
</div>
<!--======================================================-->
</div>
</div>
</form>
</body>
</html>
3、文件上传处理程序源码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Configuration;
namespace BatchUpload
{
public class UploadHandler :IHttpHandler
{
public staticstring SystemJSONTemplate ="{{\"status\":\"{0}\",\"msg\":\"{1}\",\"url\":\"{2}\",\"urlname\":\"{3}\"}}";
//publicstring FilePageSize = ConfigurationManager.AppSettings["FilePageSize"].ToString();
staticDictionary<string, string> dic = new Dictionary<string, string>();
public voidProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
UploadFile(context.Request, context.Response);
}
public voidUploadFile(HttpRequest Request,HttpResponse Response, string UploadFiles ="UploadFiles")
{
//当前第几个块 (前端FLASH会将文件进行分块传输,后端需要判断是否完成。
int chunk = Request.Params["chunk"] != null ?int.Parse(Request.Params["chunk"]) : 0;
//文件一共拆分成了几块 chunk = chunk-1 就可以认定文件已经传完。
int chunks = Request.Params["chunks"] != null ?int.Parse(Request.Params["chunks"]) : 0;
//获取源文件名,如果jquery.plupload.js框架在前端设定unique_names: true,则在这儿上传的文件名是以UUID的形式体现。
string strSourceFileName = Request.Params["name"];
string SQLChars = ";,%";
if (!string.IsNullOrEmpty(SQLChars))
{
//在静态方法中,定义变量实例,这个不太合理。但是这个变量的值是恒定的,不会出现并发的问题。
string[] strSQLChars = SQLChars.Split(',');
//检查特殊字符
foreach (string strkey in strSQLChars)
{
//包含关键字
if (strSourceFileName.ToLower().IndexOf(strkey.ToLower())> -1)
{
Response.Write(string.Format(SystemJSONTemplate, "0", strkey,"0", "0"));
return;
}
}
}
//构建目标文件名
string strTargetFileName = string.Empty;
if (chunk == 0)
{
dic.Remove("tempTargetFileName");
strTargetFileName = Guid.NewGuid().ToString() +Path.GetExtension(strSourceFileName);
dic.Add("tempTargetFileName", strTargetFileName);
}
else if (chunk < chunks)
{
strTargetFileName = (string)dic["tempTargetFileName"];
}
try
{
//创建上传文件目录
string strUploadFileDirectory =HttpContext.Current.Server.MapPath("~/");
strUploadFileDirectory=strUploadFileDirectory+UploadFiles +"/" + DateTime.Now.ToString("yyyy") +
"/" +DateTime.Now.ToString("MM") + "/";
//创建文件上传的目录
if (!Directory.Exists(strUploadFileDirectory))
{
Directory.CreateDirectory(strUploadFileDirectory);
}
//数据库保存地址
string dbUploadFile = "/" + UploadFiles + "/"+ DateTime.Now.ToString("yyyy") + "/" + DateTime.Now.ToString("MM")+ "/";
//关键代码。以chunk来判断是否是新增文件,或者是向某一个文件后面写入流数据。
FileStream fs = new FileStream(strUploadFileDirectory +strTargetFileName,
chunk == 0 ? FileMode.OpenOrCreate : FileMode.Append);
Byte[] buffer = null;
if (Request.ContentType == "application/octet-stream"&& Request.ContentLength > 0)
{
buffer = new Byte[Request.InputStream.Length];
Request.InputStream.Read(buffer, 0, buffer.Length);
}
else if(Request.ContentType.Contains("multipart/form-data") &&Request.Files.Count > 0 && Request.Files[0].ContentLength > 0)
{
buffer = newByte[Request.Files[0].InputStream.Length];
Request.Files[0].InputStream.Read(buffer, 0,buffer.Length);
}
//文件已经分包上传完成,需要将信息返回前端
if (chunk == chunks - 1)
{
//将结果输出到前端
Response.Write(string.Format(SystemJSONTemplate,"1", strSourceFileName + ":" + strTargetFileName +":" + dbUploadFile, "0", "0"));
}
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
catch (Exception ex)
{
throw ex;
}
}
public boolIsReusable
{
get
{
return false;
}
}
}
}