上面的html代码与示例B的格式差不多,只是增加了两个input元素方便我们来测试;重点在js代码中,由上面介绍可以看到FormData的构造只能是HTMLFormElement,所以我们通过document.getElementById("form_c")来获取这个表单的对象传递给它;
然后,我们用普通的$.ajax提交FormData对象到后台进行上传,至于后台我们参照示例A的方式来获取文件信息,不用做什么特殊额处理,只是我们返回的信息是Json数据,代码如:
[HttpPost] public JsonResult C() { Thread.Sleep(1000 * 5); var response = new MoResponse(); var sbLog = new StringBuilder("开始处理..."); try { sbLog.AppendFormat("账号:{0}<br/>", Request.Params["userName"]); sbLog.AppendFormat("密码:{0}<br/>", Request.Params["userPwd"]); var fileCount = Request.Files.Count; //访问上传文件地址 var path = @"http://localhost:1010/{0}"; //保存文件地址 var uploadPath = @"D:\D\TTest"; sbLog.AppendFormat("上传文件目录:{0}<br/>", uploadPath); sbLog.AppendFormat("上传文件量:{0}<br/>", fileCount); for (int i = 0; i < fileCount; i++) { var file = Request.Files[i]; if (file == null || string.IsNullOrEmpty(file.FileName)) { continue; } var fileName = file.FileName; var fileNewName = DateTime.Now.Ticks + fileName; sbLog.AppendFormat("第:{0}个文件名称:{1}新名称:{2}下载地址:<a href='https://www.jb51.net/article/{3}' target='_blank'>{2}</a><br/>", i + 1, fileName, fileNewName, string.Format(path, fileNewName)); file.SaveAs(Path.Combine(uploadPath, fileNewName)); response.Status = 1; } } catch (Exception ex) { sbLog.AppendFormat("异常信息:{0}", ex.Message); } finally { response.Data = sbLog.ToString(); } return Json(response); }
下面我们看一下添加"提交"按钮执行后返回的效果,可以看出提交后没有跳转到action指向的路由,这样用户体验就好多了:
. 示例D - 自定义上传插件,Request.Files获取上传文件并提交表单内容
首先,我发个插件下载地址shenniu.upfile-0.0.1.js,只需要在试图或者html页面引用jquery-1.10.2.min.js库和这个插件,我们就可以这样使用:
<script> $(function () { //示例D代码 //初始化插件 var shenniu = new shenniu_UpFile({ url: "/Error/D_A", fileEleName: "filesd" }); //提交事件 $("#form_d button[type='button']").click(function () { var msg = $("#msg_d"); var btnSave = $(this); btnSave.attr("disabled", "disabled"); msg.html("上传中.."); //上传文件 shenniu.submitFun(function (data) { try { var result = JSON.parse(data); //上传成功,保存数据 if (result.Status == 1) { //增加上传成功的文件名称到表单 var hidFileNames = $("#form_d input[name='hidFileNames']"); if (hidFileNames.length <= 0) { $("#form_d").append("<input type='hidden' value='" + result.Data + "'/>"); else { hidFileNames.val(result.Data); } //获取表单键值对,提交表单数据 var param = $("#form_d").serialize(); var action = $("#form_d").attr("action"); $.post(action, param, function (res) { msg.html(res.Status == 1 ? "保存成功<br/>" + res.Data : "保存失败"); }); } else { msg.html(result.Data); } } catch (e) { console.log(e.message); } finally { btnSave.removeAttr("disabled"); } }); }); }) </script>
使用插件的地方和js关键点已经通过代码注释备注好了,朋友们可仔细阅读下,这里要将的是插件上传文件和提交表单数据的逻辑;我们分析下:
form表单中通常有其他的属性数据
form表单的提交数据的后台地址可能和上传文件的后台地址不一样
需要单独上传文件后,返回是否上传成功,再提交form表单的其他数据到后台
由上面几点插件的参数定义为:
var defOption = { url: "http://www.cnblogs.com/wangrudong003/", //上传路由地址,注:1.目前通过该地址上传文件成功后,返回的信息是text/plain 2.跨域暂未考虑 fileEleName: "fileName", //上传input file控件的唯一名称 uid: new Date().getTime(), //防重复 backFun: function () { } //回调函数 };
这个自定义插件原理和几个重点是:
自动创建一个iframe(用来做无刷新体验),iframe里面创建一个form表单,form表单里面只包含要上传的文件file对象,最终把iframe加入到视图页面中