实现原理

目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传。思考半天,想到通过创建动态表单包裹上传文件域,利用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. 求助:IIS中部署WCF,生成的WSDL中怎么把“计算机名”改成IP==找到一个解决办法

    环境:win2003 IIS6 VS2008 求助: 如图: 有朋友遇到过这个问题吗?还是说这个不是问题? 先 谢谢了! 补充配置文件: 代码 目前解决办法: 修改IIS的配置: 如图: 解决后的ws ...

  2. Paxos算法(转)

    Paxos算法的难理解与算法的知名度一样令人敬仰,从我个人的经历而言,难理解的原因并不是该算法高深到大家智商不够,而在于Lamport在表达该算法时过于晦涩且缺乏一个完整的应用场景.如果大师能换种思路 ...

  3. Mvc自定义分页控件

    MVC开发分页常常使用第三方控件,生成的分页HTML带有版权申明,虽然免费,但是总有的别扭.于是,某日,楼主闲来蛋疼,折腾了个自定义分页控件: 先来展示下效果图: 1>当分页不超过10页的时候, ...

  4. 查看linux虚拟机ssh服务是否开启

    知识准备: 1.ssh和sshd的区别: 2.ssh服务进程默认地址:/etc/init.d/ssh 查看ssh服务是否开启 service ssh status 或者: /etc/init.d/ss ...

  5. bootstrap -- 一个标签中,同时有 col-xs , col-sm , col-md , col-lg

    .col-xs- 超小屏幕 手机 (<768px) .col-sm- 小屏幕 平板 (≥768px) .col-md- 中等屏幕 桌面显示器 (≥992px) .col-lg- 大屏幕 大桌面显 ...

  6. 【JS】Beginner9:Arrays

    1.Lists of any kind of data 2.Index to retreve an element from the array 0 3.[] .length; .pop()/push ...

  7. oracle rac 学习(转载)

    一. RAC 并发 RAC 的本质是一个数据库,运行在多台计算机上的数据库,它的主要任务是数据库就是事务处理,它通过 Distributed Lock Management(DLM:分布式锁管理器)  ...

  8. HIbernate学习笔记(一) 了解hibernate并搭建环境建立第一个hello world程序

    Hibernate是一个开放源代码的ORM(对象关系映射)框架,它对JDBC进行了轻量级的封装,Java程序员可以使用面向对象的编程思维来操纵数据库,它通过对象属性和数据库表字段之间的映射关系,将对象 ...

  9. POJ2192 - Zipper(区间DP)

    题目大意 给定三个字符串s1,s2,s3,判断由s1和s2的字符能否组成字符串s3,并且要求组合后的字符串必须是s1,s2中原来的顺序. 题解 用dp[i][j]表示s1的前i个字符和s2的前j个字符 ...

  10. (Step by Step)How to setup IP Phone Server(VoIP Server) for free.

    You must have heard about IP Phone and SIP (Software IP Phone).Nowadays standard PSTN phone are bein ...