上傳文件,使用FormData進行Ajax請求,jsoncallback跨域

經過傳統的form表單提交的方式上傳文件: javascript

 

 

<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="上傳"/>
</form>
View Code

 

不過傳統的form表單提交會致使頁面刷新,可是在有些狀況下,咱們不但願頁面被刷新,這種時候咱們都是使用Ajax的方式進行請求的: php

 

$.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表單中的全部參數傳遞到服務端。html

 
可是上述方式,只能傳遞通常的參數,上傳文件的文件流是沒法被序列化並傳遞的。
不過現在主流瀏覽器都開始支持一個叫作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 = 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 java

 

使用FormData,進行Ajax請求並上傳文件web

<form id= "uploadForm">
      <p >指定文件名: <input type="text" name="filename" value= ""/></p >
      <p >上傳文件: <input type="file" name="file"/></ p>
      <input type="button" value="上傳" onclick="doUpload()" />
</form>

function doUpload() {
     var formData = 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"  才能夠上傳文件,而後這裏面最後實現了上傳,可是新的問題又來了,這中方法,文件上傳以後,會跳轉到另一個頁面,這樣交互性很是不友好,因此,又想改進爲無刷新的,ajax

JavaScript:json

<script type="text/javascript">

            function doUpload() {

                var formData = 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 = JSON.stringify(returndata);

                        alert(vData);

                    },

                    error: function(returndata) {

                        var vData = JSON.stringify(returndata);

                        alert(vData);

                    }

                });

            }
        </script>  
View Code

HTML:跨域

        <form id="uploadForm">


            <p>指定文件名:

                <input type="text" name="filename" value="" />

            </p>

            <p>上傳文件:

                <input type="file" name="file" />

                </ p>

                <input type="button" value="上傳" 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瀏覽器

跨域解決方案:jsonp, jsoncallback

js:  jsonp 格式ajax

$.ajax({
        'url':'http://100.80.62.40:8080/WebService.asmx/HelloWorld',
        'type':'POST',
        'contentType': "application/json; charset=utf-8",
        'data':'',
        'dataType':'json',
        //dataType: "jsonp",
        //jsonp: "jsoncallback",
        'success': function(response){
            console.log(response);
            console.log(response.d);
            console.log(JSON.parse(response.d));
        }
    });
View Code

關於JSON.parse解析的問題,其實這個是小問題,JSON 的這個正確格式爲 :{「result」:」success」},注意內容必定爲雙引號,不能爲單引號,單引號就會出現如此的錯誤。故在webservic方法中爲正確使用 json格式,使用將雙引號轉義。

 jsonp: "jsonp", //傳遞給請求處理程序或頁面的,用以得到jsonp回調函數名的參數名(默認爲:callback)
 jsonpCallback: "jsonpCallback", //自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名

//        function jsonpCallback(result) {//這裏是回調方法
//            alert(result.msg);
//            $("ws1").remove();//注意回調後若是有可能請執行刪除操做
//        }

string jsonCallBack = Context.Request["jsoncallback"];  //HttpContext.Current.Request["jsonp"] 

Context.Response.ContentType = "text/html; charset=utf-8";
Context.Response.Write(jsonCallBack +"("+數據+")");
Context.Response.End();

Web.Config

system.web, 注意關於WebService及其子標籤的寫法

 

<system.web>
    <compilation targetFramework="4.5.2" debug="true"/>
    <httpRuntime targetFramework="4.5.2"/>
    <httpModules>
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
    </httpModules>
    <!--跨域請求-->
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>
View Code

 

第二部分,這一塊是爲了解決JS 本源策略,跨域的問題。容許非同源調用

 

<system.webServer>
    <!--解決跨域請求 by wys -->
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
        <add name="Access-Control-Allow-Headers" value="x-requested-with,content-type"/>
        <add name="Access-Control-Allow-Origin" value="*" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
View Code

 

http://blog.csdn.net/shuai_wy/article/details/51184950

相關文章
相關標籤/搜索