本文详解如何利用jQuery插件uploadify实现Ajax效果的图片上传功能。通过配置CSS、JS及HTML结构,结合C#一般处理程序处理后端逻辑,实现文件队列管理、进度显示及上传成功后的图片预览,并提供完整源码参考。
uploadify插件简介与选型
为了深入掌握Ajax效果的图片上传技术,笔者花费大量时间调研了多种第三方控件,最终选定uploadify。该控件的主要优势在于上手简单,易于集成。
在开始之前,建议参考相关文档资料,以下内容为整理后的核心要点。
uploadify提供丰富的可配置选项。
| 需要参数类型 | 参数名字 | 解释 |
|---|---|---|
| (布尔型) | auto | 当文件被添加到队列时,自动上传。 |
| (字符串) | buttonImg | 浏览按钮的背景图片路径。 |
| (字符串) | buttonText | 默认在按钮上显示的文本。 |
| (字符串) | cancelImg | 取消按钮的背景图片路径。 |
| (字符串) | checkScript | 用以检查服务器上已存在文件的后台脚本的路径。【译者注:应该是ajax方式】 |
| (字符串) | displayData | 在上传过程中显示在队列里的数据类型。 |
| (字符串) | expressInstall | expressInstall.swf文件的路径。 |
| (字符串) | fileDataName | 后台脚本中要处理的file域的名称。【译者注:就是type为file的input的name值】 |
| (字符串) | fileDesc | 在浏览窗口底部的文件类型下拉菜单中显示的文本。 |
| (字符串) | fileExt | 允许上传的文件后缀。【译者注:.jpg/.png等】 |
| (字符串) | folder | 上传文件夹的路径,文件上传后将被保存于此。 |
| (整型) | height | 浏览按钮的高度。 |
| (布尔型) | hideButton | 设置为true将隐藏flash按钮,这样你就可以为下面的div元素定义样式。 |
| (字符串) | method | 向后台脚本放送数据的表单方法。 |
| (布尔型) | multi | 设置为true将允许多文件上传。 |
| (字符串) | queueID | 页面中,你想要用来作为文件队列的元素的id。 |
| (整型) | queueSizeLimit | 上传队列中所允许的文件数量。 |
| (布尔型) | removeCompleted | 设置为true将自动移除队列中已经完成上传的项目。 |
| (布尔型) | rollover | 设置为true将激活浏览按钮的鼠标划过状态。 |
| (字符串) | script | 处理文件上传的后台脚本的路径。 |
| (字符串) | scriptAccess | 设置在主swf文件中的脚本访问模式。 |
| (JSON) | scriptData | 在文件上传时,应该被发送给后台脚本的一个包含name/value键值对以及一些额外信息的json对象。 |
| (整型) | simUploadLimit | 允许同时上传的文件数量。 |
| (整型) | sizeLimit | 上传文件的大小限制,单位为字节。 |
| (字符串) | uploader | uploadify.swf文件的路径。 |
| (整型) | width | 浏览按钮的宽度。 |
| (字符串) | wmode | flash文件的wmode。 |
同时支持多种事件回调以处理不同状态。
| (函数) | onAllComplete | 当上传队列中的所有文件都完成上传时触发。 |
| (函数) | onCancel | 当从上传队列每移除一个文件时触发一次。 |
| (函数) | onCheck | 在上传开始之前,如果检测到一个同名文件时触发。 |
| (函数) | onClearQueue | 当uploadifyClearQueue()方法被调用时触发。 |
| (函数) | onComplete | 每完成一次文件上传时触发一次。 |
| (函数) | onError | 当上传返回错误时触发。 |
| (函数) | onInit | 当Uploadify实例被载入时触发。 |
| (函数) | onOpen | 当上传队列中的一个文件开始上传时就触发一次。 |
| (函数) | onProgress | 在上传过程中触发。 |
| (函数) | onQueueFull | 当文件数量达到上传队列限制时触发。 |
| (函数) | onSelect | 每向上传队列添加一个文件时触发。 |
| (函数) | onSelectOnce | 每向上传队列添加一个或一组文件时触发。 |
| (函数) | onSWFReady | 当flash文件载入完成时触发。 |
此外,该插件还封装了若干常用方法。
| .uploadify() | 创建Uploadify上传组件的一个实例。 | |
| .uploadifyCancel() | 从上传队列移除一个文件。如果文件正在上传,该方法将先取消上传,然后再将文件移除出上传队列。 | |
| .uploadifyClearQueue() | 将所有文件移除出上传队列,并且取消正在执行的所有上传。 | |
| .uploadifySettings() | 改变Uploadify组件的可选参数。 | |
| .uploadifyUpload() | 触发上传。 |
实际开发中无需记忆所有参数,只需查阅文档了解所需参数即可。
前端环境配置与HTML结构
以下是实现该功能的核心代码示例,供参考。
首先在HTML的<head>部分引入CSS样式表,路径需根据实际项目结构调整:<link href="../Plugin/uploadify.css" rel="stylesheet" type="text/css" />
接着在<head>中引入必要的JavaScript文件,需注意加载顺序,否则可能引发错误。
<script type="text/javascript" src="../js/jquery-1.4.2.min.js"></script>
<script src="../Plugin/swfobject.js" type="text/javascript"></script>
<script src="../Plugin/jquery.uploadify.v2.1.4.min.js" type="text/javascript"></script>
请确保路径指向正确。由于uploadify基于jQuery开发,必须先加载jQuery库,再加载uploadify脚本,顺序不可颠倒。
接下来是核心的HTML结构代码。
<tr>
<th scope="row">图 片:</th>
<td>
<div style="float:left;width:125px;height:35px;">
<input type="file" name="uploadify" id="uploadify" /> <%--上传时的进度条--%>
</div>
<div id="fileQueue" style="float:left;height:35px;"></div>
<div style="float:left;height:35px;">
<a href="javascript:$('#uploadify').uploadifyUpload()" class="btn-lit"><span>上传</span></a>
<a href="javascript:$('#uploadify').uploadifyClearQueue()" class="btn-lit"><span>取消上传</span></a>
</div>
</td>
</tr>
<tr>
<th scope="row"> </th>
<td><asp:Image ID="pic" runat="server" /></td> <%--成功上传生成图片预览功能--%>
</tr>
建议将相关输入元素放置在form标签内的table表格中,以便更好地控制布局。
前端JavaScript接口实现
随后需要实现插件提供的接口,前端JavaScript代码如下:
//uploadify插件的自定义设置
$(document).ready(function () {
$("#uploadify").uploadify({
'uploader': '../Plugin/uploadify.swf',
'script': 'UploadImg.ashx',
'cancelImg': '../Plugin/cancel.png',
'folder': '../upload',
'buttonText': 'SELECT Pic',
'fileExt': '*.jpg;*.gif,*.png', //允许上传的文件格式为*.jpg,*.gif,*.png
'fileDesc': 'Web Image Files(.JPG,.GIF,.PNG)', //过滤掉除了*.jpg,*.gif,*.png的文件
'queueID': 'fileQueue',
'sizeLimit': '2048000', //最大允许的文件大小为2M
'auto': false, //需要手动的提交申请
'multi': false, //一次只允许上传一张图片
'onCancel': funCancel, //当用户取消上传时
'onComplete': funComplete, //完成上传任务
'OnError': funError //上传发生错误时
});
});
//用户取消函数
function funCancel(event, ID, fileObj, data) {
jBox.tip('您取消了' + fileObj.name + '操作', 'info');
return;
}
//图片上传发生的事件
function funComplete(event, ID, fileObj, response, data) {
//$("#pic").html('<img id="pic" runat="server" src=../upload/' + response + '.jpg style="width:300;height:200px;"/>');
if (response == 0) {
jBox.tip('图片' + fileObj.name + '操作失败', 'info');
return;
}
$("#pic").attr("src", "../upload/" + response).height(200).width(300);
jBox.tip('图片' + fileObj.name + '操作成功', 'info');
return;
}
//上传发生错误时。
function funError(event, ID, fileObj, errorObj) {
jBox.tip(errorObj.info);
return;
}
后端一般处理程序逻辑
后端需编写一个一般处理程序(.ashx)来处理文件上传请求,代码如下:
context.Response.ContentType = "text/plain";
context.Response.Charset = "utf-8";
HttpPostedFile file = context.Request.Files["Filedata"];
string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"]) + "\\";
if (file != null)
{
//if (File.Exists(uploadPath + file.FileName))
//{
// context.Response.Write("3"); //文件已经存在
// return;
//}
string[] fn = file.FileName.Split('.');
string ext = fn[fn.Length - 1];
string filename = DateTime.Now.ToString("yyyyMMddhhmmss")+"."+ext;
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
file.SaveAs(uploadPath + filename);
//下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失
context.Session[context.Session["userName"].ToString()] = filename;
context.Response.Write(filename);
}
else
{
context.Response.Write("0");
}
上传成功时返回文件名,失败则返回0。前端JS不直接追踪返回值,若返回0视为失败,否则动态为img标签设置src属性以显示图片。
完整源码下载链接:http://xiazai.jb51.net/201606/yuanma/jQuery-uploadify-ajax-upload(jb51.net).rar