实现原理

目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传。思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上传完毕后移除上传表单,避免与原有表单形成嵌套,导致原有的表单无法正常提交。同时该方式还支持一次上传一个文件,重复上传或者一次上传多个文件,具有较好的方便性。

代码实现

ayscUploadFile方法包含两个参数, wrapId和postMap。

wrapId被指定为要被上传表单包裹的位置id。

postMap是一个对象,主要包含以下信息:

1、表单提交地址Url

由于上传文件的表单都是enctype='multipart/form-data',不能使用post提交文本参数,需要使用get方式提交其他参数,因此要传递额外的参数在url中直接带上参数。

2、type参数

允许上传的文件类型

3、folder参数

指定上传文件的自定义存储子目录,默认不需要指定。

4、beforeCallback

beforeCallback为ajax提交表单之前事件触发函数

5、successCallback

successCallback为上传成功后的处理函数

6、errorCallback

errorCallback为ajax异步提交表单失败后的处理函数

函数功能

1、异步上传文件

2、支持批量上传文件

function ayscUploadFile(wrapId, postMap){
/*判断被包裹的id是否存在*/
if(wrapId == "undefined" || wrapId.length == 0){
alert("被包裹的id不存在");
return false;
}else{
wrapId = wrapId.indexOf("#") >= 0 ? wrapId : "#"+ wrapId;
} if(!(typeof(postMap) == "object")){
alert("上传配置参数错误");
return false;
} var url = postMap["url"];
/*判断url是否为空*/
if(!(url != "undeifned" && url.length > 0)){
alert("上传地址错误");
return false;
}else{
/*上传文件类型*/
var type = ("type" in postMap) ? postMap["type"] : "";
/*自定义上传文件目录*/
var folder = ("folder" in postMap) ? postMap["folder"] : ""; /*url地址加上限制上传文件的类型*/
if(type.length > 0){
url = adArgsToUrl(url, "type", type);
} /*url地址加上自定义的上传文件存储位置*/
if(folder.length > 0){
url = adArgsToUrl(url, "folder", folder);
}
} /*表单id*/
var formId = "frm_"+ wrapId.replace("#", ""); /*生成表单*/
var formContent = "<form id='"+ formId +"' name='"+ formId +"' action='"+ url+"' method='post' enctype='multipart/form-data'></form>"; /*将表单包裹在指定的id上*/
if($("form[id="+ formId +"]").length == 0){
$(wrapId).wrap(formContent);
} /*验证表单中文件域是否已经选择文件*/
var checkForm = true;
$("form[id="+ formId +"] > :file").each(function(){
if(this.value.length == 0){
alert("尚未选择文件,请选择文件");
checkForm = false; return;
}
}); if(checkForm){
/*回调方法*/
var beforeCallback = postMap["beforeCallback"];
var successCallback = postMap["successCallback"];
var errorCallback = postMap["errorCallback"]; /*异步上传文件*/
$("#" + formId).ajaxSubmit({
dataType:"html",
beforeSend:function(httpRequest){
if(typeof(beforeCallback) == "function"){
if(!beforeCallback.call(null, formId)){
httpRequest.abort();
alert("终止执行ajax异步提交")
}
}else{
alert("正在上传文件,请耐心等待,不要关闭浏览器");
}
},
success:function(responseText){
alert(responseText)
/*重置表单,确保允许继续添加上传文件*/
resetForm(); if(typeof(successCallback) == "function"){
/*解析返回结果*/
successCallback.call(null, parseResultMap(responseText));
}else{
alert("文件上传成功");
}
},
error:function(responseText){
resetForm(); if(typeof(errorCallback) == "function"){
/*解析返回结果*/
errorCallback.call(null);
}else{
alert("网络通讯异常,上传失败,请重新上传或稍后再试");
}
}
});
} /*重置表单信息*/
function resetForm(){
/*重置上传表单内容,方便上传新的文件*/
$("#"+ formId).clearForm(); /*移除表单,恢复原样,避免表单嵌套*/
$(wrapId).unwrap("#"+ formId);
} /*解析返回结果*/
function parseResultMap(responseText){
var resultMap = {};
var jsonObject = eval("("+ responseText +");"); var fileName = ("fileName" in jsonObject) ? jsonObject["fileName"] : "";
var fileSize = ("fileSize" in jsonObject) ? jsonObject["fileSize"] : "";
var fileUrl = ("fileKey" in jsonObject) ? jsonObject["fileKey"] : "";
var fileExt = ("fileExt" in jsonObject) ? jsonObject["fileExt"] : "";
var message = ("message" in jsonObject) ? jsonObject["message"] : "上传失败";
var uploadState = ("uploadState" in jsonObject) ? jsonObject["uploadState"] : "0"; fileSize = (parseInt(fileSize)/1024).toFixed(2); resultMap["fileName"] = fileName;
resultMap["fileSize"] = fileSize;
resultMap["fileUrl"] = fileUrl;
resultMap["fileExt"] = fileExt;
resultMap["message"] = message;
resultMap["uploadState"] = uploadState; return resultMap;
}
}

上述函数使用需要引入的外部脚本文件

    <script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>

另外特别说明:

beforeSend方法实际上实在$.ajax中,他接收一个XMLHTTPRequest参数,因此若要挂起ajax请求,执行XMLHTTPRequest的abort()即可。

parseResultMap方法为接收服务器返回的数据并进行处理。、

ajaxSubmit方法实现的异步提交实际上还是jquery的$.ajax的进一步封装,方便了大家的使用.

批量上传文件

该方法也支持一次上传多个文件。但必须创建多个文件域控件,到时上传表单包含这些文件域,实现批量上传文件。

<div id="divWrap">
<input type="file" id="fileOne" name="fileOne" value="" />
<input type="file" id="fileTwo" name="fileTwo" value="" />
<input type="file" id="fileThree" name="fileThree"value="" />
<input type="file" id="fileFour" name="fileFour" value="" />
</div>

需要批量上传的文件域必须被包裹在指定的包裹id里(divWrap),包裹id用于指定动态表单的创建位置。上面的html代码,就是一个包含多个文件域的实例,这样就可以一次上传多个文件。

另外一种 方式可以曲线实现批量上传。用户每上传完毕一个文件后,允许用户继续上传文件,回调函数把服务器返回的上传文件信息输出给页面,页面记录下用户所有的上传文件信息。

参考资料

http://api.jquery.com/Ajax_Events/

http://baike.baidu.com/link?url=zsF_hdb0eZGOtzG2-fwLiHSPJDw0NqZ9GqXScpmBoF3Y_UauuT3HlJrt6raotAsVbVg-_TZQ6zdkh-GYZ91Wn_

http://www.w3school.com.cn/xmldom/dom_http.asp

http://www.cnblogs.com/beniao/archive/2008/03/29/1128914.html

https://github.com/malsup/form

利用jquery.form实现异步上传文件的更多相关文章

  1. 关于JQuery.form.js异步上传文件点滴

    好久没动代码了,前几天朋友委托我帮忙给做几个页面,其中有个注册带图片上传的页面.已之前的经验应该很快就能搞定,没想到的是搞了前后近一天时间.下面就说说异步上传的重要几个点,希望自己下次遇到此类问题的时 ...

  2. 【转】JQuery插件ajaxFileUpload 异步上传文件(PHP版)

    前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错,但是由于手机不支持flash,所以不得不再找一个文件上传插件来用了.后来发现a ...

  3. JQuery插件ajaxFileUpload 异步上传文件(PHP版)

    太久没写博客了,真的是太忙了.善于总结,进步才会更快啊.不多说,直接进入主题. 前几天想在手机端做个异步上传图片的功能,平时用的比较多的JQuery图片上传插件是Uploadify这个插件,效果很不错 ...

  4. JQuery插件ajaxFileUpload 异步上传文件

    一.先对ajaxFileUpload插件的语法参数进行讲解 原理:ajaxfileupload是通过监听iframe的onload方法来实现, 当从服务端处理完成后,就触发iframe的onload事 ...

  5. ajax上传文件 基于jquery form表单上传文件

    <script src="/static/js/jquery.js"></script><script> $("#reg-btn&qu ...

  6. jquery.form.js mvc 上传文件 layer 选择框与等待效果

    HTML <form role="form" id="form1"> <div class="form-group"> ...

  7. ASP.NET MVC 使用jquery.form.js 异步上传 在IE下返回值被变为下载的解决办法

    错误记录: <script type="text/javascript"> $(function () { $(document).off("ajaxSend ...

  8. Jquery~跨域异步上传文件

    先说明白 这个跨域异步上传功能我们借助了Jquery.form插件,它在异步表单方面很有成效,而跨域我们会在HTTP响应头上添加access-control-allow-method,当然这个头标记只 ...

  9. struts2 jquery ajaxFileUpload 异步上传文件

    网上搜集的,整理一下. 一.ajaxFileUpload 实现异步上传文件利用到了ajaxFileUpload.js这个文件,这是别人开发的一个jquery的插件,可以实现文件的上传并能够和strut ...

随机推荐

  1. URAL1029. Ministry(DP+路径)

    链接 路径麻烦啊 很多细节 倒回去搜一遍 卡了一节数据库.. #include <iostream> #include<cstdio> #include<cstring& ...

  2. Eclipse 中使用Genymotion 作为模拟器的步骤

    我这里是先安装的genymotion, 后安装的eclipse. 1:安装genymotion 无难度, 直接安装就行了. 2:安装eclipse 下载adt即可, 解压运行. 3:运行eclipse ...

  3. C# winform自定义Label控件使其能设置行距

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  4. Xfire soapHeader的WebService权限控制forjava

    研究webservice有一段时间了,觉得用soapHeader来控制访问比较简单,特贴出代码以供大家分享 1.我们可以做一个很简单的ws测试,服务端的接口代码如下: package ws; //Ge ...

  5. STL总结之functor

    STL中仿函数是重要的组成部分.所谓的仿函数就是通过重载括号运算符实现的, 如下: STL库中都是泛型仿函数如小于操作: STL中定义了许多有用的操作,如less(小于), less_equal(小于 ...

  6. [liu yanling]软件测试技巧

    1.添加.修改功能 (1)是否支持tab键 (2)是否支持enter键 (3)不符合要求的地方是否有错误提示 (4)保存后,是否也插入到数据库中 (5)字段唯一的,是否可以重复添加 (6)对编辑页列表 ...

  7. Java笔记(十二)……类中各部分加载顺序及存放位置问题

    什么时候会加载类 使用到类中的内容时加载,三种情况: 创建对象:new StaticDemo(); 使用类中的静态成员:StaticCode.num = 9;  StaticCode.getNum() ...

  8. wuzhicms后台菜单的添加

    红色部分都是从菜单管理处添加而来.只有少数是自定义的. 开发一个模块,首先就是菜单的管理.而,不需要的功能也可以在在菜单管理处隐藏或删除. 添加菜单:

  9. 五指CMS发布1.4版本,更多的新功能

    五指cms v1.4变更: 新增内容手动分页新增百度地图新增订单管理模块新增订单地址管理增加Microsoft YaHei字体新增推广邀请模块新增私密下载,下载函数 新增百度地图新增筛选功能 修正全局 ...

  10. ARFF文件格式

    Attribute -Relation File Format (ARFF) 此文档翻译自http://www.cs.waikato.ac.nz/~ml/weka/arff.html.文档写的比较粗糙 ...