首页 > 代码库 > 上传文件,使用FormData进行Ajax请求,jsoncallback

上传文件,使用FormData进行Ajax请求,jsoncallback

通过传统的form表单提交的方式上传文件:

 

 

技术分享
<form id= "uploadForm" action= "http://localhost:8080/cfJAX_RS/rest/file/upload" method= "post" enctype ="multipart/form-data">     <h1 >测试通过Rest接口上传文件 </h1>     <p >指定文件名: <input type ="text" name="filename" /></p>     <p >上传文件: <input type ="file" name="file" /></p>     <p >关键字1: <input type ="text" name="keyword" /></p>     <p >关键字2: <input type ="text" name="keyword" /></p>     <p >关键字3: <input type ="text" name="keyword" /></p>     <input type ="submit" value=http://www.mamicode.com/"上传"/></form>
View Code

 

不过传统的form表单提交会导致页面刷新,但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的:

 

技术分享
$.ajax({     url : "http://localhost:8080/STS/rest/user",     type : "POST",     data : $( #postForm).serialize(),     success : function(data) {          $( #serverResponse).html(data);     },     error : function(data) {          $( #serverResponse).html(data.status + " : " + data.statusText + " : " + data.responseText);     }});
View Code

 

如上,通过$(‘#postForm‘).serialize()可以对form表单进行序列化,从而将form表单中的所有参数传递到服务端。

 
但是上述方式,只能传递一般的参数,上传文件的文件流是无法被序列化并传递的。
不过如今主流浏览器都开始支持一个叫做FormData的对象,有了这个FormData,我们就可以轻松地使用Ajax方式进行文件上传了。
 
关于FormData及其用法
 
FormData是什么呢?我们来看看Mozilla上的介绍。
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件. 
 
所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
 
参见:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/FormData
 
这里只展示一个通过from表单来初始化FormData的方式
<form enctype="multipart/form-data" method="post" name="fileinfo">
技术分享
var oData = http://www.mamicode.com/new FormData(document.forms.namedItem("fileinfo" ));oData.append( "CustomField", "This is some extra data" );var oReq = new XMLHttpRequest();oReq.open( "POST", "stash.php" , true );oReq.onload = function(oEvent) {      if (oReq.status == 200) {          oOutput.innerHTML = "Uploaded!" ;     } else {          oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";     }};oReq.send(oData);
View Code

参见:https://developer.mozilla.org/zh-CN/docs/Web/Guide/Using_FormData_Objects

 

使用FormData,进行Ajax请求并上传文件

技术分享
<form id= "uploadForm">      <p >指定文件名: <input type="text" name="filename" value= http://www.mamicode.com/""/></p >      <p >上传文件: <input type="file" name="file"/></ p>      <input type="button" value=http://www.mamicode.com/"上传" onclick="doUpload()" /></form>function doUpload() {     var formData = http://www.mamicode.com/new FormData($( "#uploadForm" )[0]);     $.ajax({          url: http://localhost:8080/cfJAX_RS/rest/file/upload ,          type: POST,          data: formData,          async: false,          cache: false,          contentType: false,          processData: false,          success: function (returndata) {              alert(returndata);          },          error: function (returndata) {              alert(returndata);          }     });}
View Code

 

由于通过Ajax只能应付一些简单的文字类的传输,上传文件就捉襟见肘了,如果一直引用第三方的swf之类上传也不是一个办法,所以,一直在寻找解决文件上传的方法。找了许多方法,后来知道需要指定格式才能上传文件,就是要指定Form表单为: enctype="multipart/form-data"  才可以上传文件,然后这里面最后实现了上传,但是新的问题又来了,这中方法,文件上传之后,会跳转到另外一个页面,这样交互性非常不友好,所以,又想改进为无刷新的,

JavaScript:

技术分享
<script type="text/javascript">            function doUpload() {                var formData = http://www.mamicode.com/new FormData($("#uploadForm")[0]);                $.ajax({                    url: http://localhost:34181/HomeService.asmx/UploadFile?jsoncallback=?,                    type: POST,                    data: formData,                    async: false,                    cache: false,                    contentType: false,                    processData: false,//                    dataType: "jsonp",//问题就在这里,如果用了jsonp,那么后台就接收不到文件流,无法获得文件流,就没办法把文件写入服务器。如果不指定,就是注释掉,虽然ajax提交之后,还是跑到error那里去,但是文件已经是成功写入服务器的了。                    jsonp: "jsoncallback",                    success: function(returndata) {                        var vData =http://www.mamicode.com/ JSON.stringify(returndata);                        alert(vData);                    },                    error: function(returndata) {                        var vData =http://www.mamicode.com/ JSON.stringify(returndata);                        alert(vData);                    }                });            }        </script>  
View Code

HTML:

技术分享
        <form id="uploadForm">            <p>指定文件名:                <input type="text" name="filename" value=http://www.mamicode.com/"" />            </p>            <p>上传文件:                <input type="file" name="file" />                </ p>                <input type="button" value=http://www.mamicode.com/"上传" onclick="doUpload()" />     </form>
View Code

  后台(WebService):

技术分享
/// <summary>        /// 上传文件        /// </summary>        /// <returns></returns>        [WebMethod(EnableSession = true)]        public void UploadFile()        {            HttpContext.Current.Response.ContentType = "application/json;charset=utf-8";            string jsonCallBackFunName = HttpContext.Current.Request.Params["jsoncallback"].ToString();//这里如果前台没有用jsonp,那么获取到的是一个?,所以处理完之后,前台是没法获取到服务器返回的内容的。            //上面代码必须,不能注释            //中间代码执行自己的业务操作,可返回自己的任意信息(多数据类型)            string strJson = "";            HttpFileCollection files = HttpContext.Current.Request.Files;            string strFileName = HttpContext.Current.Request["filename"];            byte[] b = new byte[files[0].ContentLength];            System.IO.Stream fs = (System.IO.Stream)files[0].InputStream;            fs.Read(b, 0, files[0].ContentLength);            ///定义并实例化一个内存流,以存放提交上来的字节数组。            MemoryStream m = new MemoryStream(b);            ///定义实际文件对象,保存上载的文件。            FileStream f = new FileStream(Server.MapPath("\\UploadFile") + "\\"             + files[0].FileName, FileMode.Create);            ///把内内存里的数据写入物理文件            m.WriteTo(f);            m.Close();            f.Close();            f = null;            m = null;            if (strJson == "")            {                strJson = "0";            }            //下面代码必须,不能注释            HttpContext.Current.Response.Write(string.Format("{0}({1})", jsonCallBackFunName, strJson));            HttpContext.Current.Response.End();        }
View Code

 

转:http://yunzhu.iteye.com/blog/2177923

 

 

 

 

 

上传文件,使用FormData进行Ajax请求,jsoncallback