使用jQuery异步上传文件的方法 技术背景 在Web开发中,文件上传是一个常见的需求。传统的表单提交会导致页面刷新,影响用户体验。而异步文件上传可以在不刷新页面的情况下完成文件上传,提升用户体验。借助HTML5的FormData
和File API
,结合jQuery的$.ajax()
方法,可以轻松实现异步文件上传。
实现步骤 HTML5支持下的异步文件上传 HTML部分 :创建包含文件输入框和上传按钮的表单,以及用于显示上传进度的progress
元素。1 2 3 4 5 <form enctype ="multipart/form-data" > <input name ="file" type ="file" /> <input type ="button" value ="Upload" /> </form > <progress > </progress >
JavaScript部分 :对文件进行验证,并使用$.ajax()
方法提交表单数据。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 $(':file' ).on ('change' , function ( ) { var file = this .files [0 ]; if (file.size > 1024 ) { alert ('max upload size is 1k' ); } }); $(':button' ).on ('click' , function ( ) { $.ajax ({ url : 'upload.php' , type : 'POST' , data : new FormData ($('form' )[0 ]), cache : false , contentType : false , processData : false , xhr : function ( ) { var myXhr = $.ajaxSettings.xhr (); if (myXhr.upload ) { myXhr.upload .addEventListener ('progress' , function (e ) { if (e.lengthComputable ) { $('progress' ).attr ({ value : e.loaded , max : e.total , }); } }, false ); } return myXhr; } }); });
HTML5不支持时的回退方案(隐藏iframe技术) HTML部分 :创建表单并将其目标设置为隐藏的iframe。1 2 3 4 5 <form target ="iframe" action ="" method ="post" enctype ="multipart/form-data" > <input name ="file" type ="file" /> <input type ="button" value ="Upload" /> </form > <iframe name ="iframe" id ="iframe" style ="display:none" > </iframe >
JavaScript部分 :可以通过监听iframe的onLoad
事件来处理上传结果。但在Chrome中,需要使用cookie来模拟onLoad
事件。使用插件实现异步文件上传 以jQuery File Upload
插件为例:
安装插件 :在项目中添加jquery.ui.widget.js
、jquery.iframe-transport.js
和jquery.fileupload.js
。HTML部分 :创建文件输入框。1 <input id ="upload" name ="upload" type ="file" />
JavaScript部分 :编写上传文件的方法。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function uploadFile (element ) { $(element).fileupload ({ dataType : 'json' , url : '../DocumentUpload/upload' , autoUpload : true , add : function (e, data ) { data.formData = { files : data.files [0 ] }; data.submit (); }, done : function (e, data ) { }, progress : function (e, data ) { }, fail : function (e, data ) { }, stop : function ( ) { } }); } $(document ).ready (function ( ) { uploadFile ($('#upload' )); });
服务器端处理 :编写MVC控制器和操作来处理文件上传。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class DocumentUploadController : Controller { [System.Web.Mvc.HttpPost ] public JsonResult upload (ICollection<HttpPostedFileBase> files ) { bool result = false ; if (files != null || files.Count > 0 ) { try { foreach (HttpPostedFileBase file in files) { if (file .ContentLength == 0 ) throw new Exception("Zero length file!" ); else } } catch (Exception) { result = false ; } } return new JsonResult() { Data = result }; } }
核心代码 使用$.ajax()
方法上传文件 1 2 3 4 5 6 7 8 9 10 11 $.ajax ({ url : 'file/destination.html' , type : 'POST' , data : new FormData ($('#formWithFiles' )[0 ]), processData : false , contentType : false }).done (function ( ){ console .log ("Success: Files sent!" ); }).fail (function ( ){ console .log ("An error occurred, the files couldn't be sent!" ); });
隐藏iframe技术上传文件 1 2 3 4 5 <form target ="iframe" action ="" method ="post" enctype ="multipart/form-data" > <input name ="file" type ="file" /> <input type ="button" value ="Upload" /> </form > <iframe name ="iframe" id ="iframe" style ="display:none" > </iframe >
使用jQuery File Upload
插件上传文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function uploadFile (element ) { $(element).fileupload ({ dataType : 'json' , url : '../DocumentUpload/upload' , autoUpload : true , add : function (e, data ) { data.formData = { files : data.files [0 ] }; data.submit (); }, done : function (e, data ) { }, progress : function (e, data ) { }, fail : function (e, data ) { }, stop : function ( ) { } }); } $(document ).ready (function ( ) { uploadFile ($('#upload' )); });
最佳实践 文件验证 :在上传文件之前,对文件的名称、大小和MIME类型进行验证,避免上传不符合要求的文件。进度条显示 :使用HTML5的progress
元素或自定义的进度条来显示文件上传的进度,提升用户体验。兼容性处理 :考虑不同浏览器的兼容性,对于不支持HTML5的浏览器,使用隐藏iframe技术作为回退方案。错误处理 :在$.ajax()
方法中添加fail
回调函数,处理文件上传过程中可能出现的错误。常见问题 浏览器兼容性问题 HTML5的File API
在一些旧版本的浏览器(如IE 9及以下)中不被支持。可以使用隐藏iframe技术或插件来解决兼容性问题。
服务器端处理问题 服务器端需要正确处理文件上传请求,确保文件能够正确保存到指定的位置。同时,需要处理文件上传过程中可能出现的错误,如文件大小超过限制、文件类型不允许等。
跨域问题 如果文件上传的目标服务器与当前页面的域名不同,可能会遇到跨域问题。可以通过设置服务器端的CORS(跨域资源共享)来解决跨域问题。