使用FormData進行Ajax請求異步上傳圖片案例

工做時遇到一個對輪播圖管理的需求,開發過程遇到些問題,總算順利解決,記錄下來供你們參考。原項目是基於SSM框架搭建的,現將Ajax圖片上傳部分分享以下:html

說明:ajax

1. 傳統的表單序列化,即經過$('#fm').serialize()能夠對form表單進行序列化,從而將form表單中的全部參數傳遞到服務端,但該方法只能傳遞通常的參數,上傳文件的文件流是沒法被序列化並傳遞的。json

2. 本文采起的方式是經過FormData對象實現的。現在主流瀏覽器都開始支持一個叫作FormData的對象,有了這個FormData,咱們就能夠輕鬆地使用Ajax方式進行文件上傳了。數組

FormData是什麼呢?
瀏覽器

XMLHttpRequest Level 2添加了一個新的接口FormData,利用FormData對象咱們能夠經過JavaScript用一些鍵值對來模擬一系列表單控件,咱們還可使用XMLHttpRequest的Send()方法來異步的提交這個"表單"。比起普通的ajax,使FormData的最大優勢就是咱們能夠異步上傳一個二進制文件。
全部主流瀏覽器的較新版本都已經支持這個對象了,好比Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。

1.dao層代碼緩存

<!--新增照片 -->服務器

   <insert id="addImage" parameterType="Image">app

             <!--自動生成id(string類型) -->框架

            <selectKey keyProperty="id" resultType="string" order="BEFORE">異步

                    SELECTUUID()

            </selectKey>

             insertinto image(id,imgName,path,uploadTime,uploader,type,displayOrder)

             values(#{id},#{imgName},#{path},#{uploadTime},#{uploader},#{type},#{displayOrder})

   </insert>

2.service層沒什麼邏輯,代碼在此省略

3.controller層代碼

@Controller

@RequestMapping("/imageManage")

public class ImageController {

       @Autowired

       private ImageService imageService;

       // 新增輪播圖片

       @RequestMapping("/addImage")

       @ResponseBody

       public void addImg(

                    @RequestParam(value ="file", required =false) MultipartFile file,

                    @RequestParam(value ="uploader", required =false) String uploader,

                     HttpServletRequestrequest) {

              String type =request.getParameter("type");

              String order =request.getParameter("order");

              Integer displayOrder =Integer.parseInt(order);

              String DirectoryName ="/upload";

              Image image =new Image();

             if (uploader !=null) {

                     image.setUploader(uploader);

              }

              image.setUploadTime(DateUtil.DateToStr(DateUtil.yyyy_MM_dd_HH_mm_ssnew Date()));

              image.setType(type);


             //System.out.println("displayOrder"+ displayOrder.getClass().getName() + displayOrder);

              String fileName =null;

             if (file !=null) {

                    //取得當前上傳文件的文件名稱

                     String myFileName = file.getOriginalFilename();

                    //System.out.println("myfileName"+myFileName);

                    // System.out.println("文件名稱"+file.getContentType());

                    //若是名稱不爲"",說明該文件存在,不然說明該文件不存在

                    if (myFileName.trim() !="") {

                           //得到圖片的原始名稱

                            String originalFilename = file.getOriginalFilename();

                           //System.out.println("originalFilename----"+originalFilename);

                           //得到圖片後綴名稱,若是後綴不爲圖片格式,則不上傳

                            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();

                           //得到上傳路徑的絕對路徑地址(/upload)-->

                            String realPath = request.getSession().getServletContext().getRealPath("/" + DirectoryName);

                           // System.out.println(realPath);

                           //若是路徑不存在,則建立該路徑

                            File realPathDirectory =new File(realPath);

                           if (realPathDirectory ==null || !realPathDirectory.exists()) {

                                   realPathDirectory.mkdirs();

                            }

                           //重命名上傳後的文件名 111112323.jpg

                            String format ="yyyyMMddHHmmss";

                            SimpleDateFormat simpleDateFormat =new SimpleDateFormat(format);

                            fileName= simpleDateFormat.format(new Date()) + suffix;

                           //定義上傳路徑 .../upload/111112323.jpg

                            File uploadFile =new File(realPathDirectory +"\\" + fileName);

                           // System.out.println(uploadFile);

                            image.setImgName(originalFilename);

                           //保存

                           try {

                                   file.transferTo(uploadFile);

                            }catch (Exception e) {

                                   e.printStackTrace();

                            }


                            image.setPath(request.getContextPath()+ DirectoryName +"\\" + fileName);


                            Image image_1 =new Image();

                            image_1.setType(type);

                           //根椐類型查詢

                            List<Image> list =imageService.getImageList(image_1);

                           if (list.size() != 0) {

                                  //圖片是滿的就替換

                                  if (list.size() == 4) {

                                         for (Image image2 : list) {

                                                if(image2.getDisplayOrder().equals(displayOrder)) {

                                                       imageService.delImage(image2);

                                                 }

                                          }

                                          image.setDisplayOrder(displayOrder);

                                         imageService.addImage(image);

                                         //圖片沒滿就日後推移

                                   }else {

                                         for (Image image2 : list) {

                                                if(!image2.getDisplayOrder().equals(displayOrder)){

                                                        image.setDisplayOrder(displayOrder);

                                                 }else {

                                                        image.setDisplayOrder(list.size()+1);

                                                 }

                                          }

                                         imageService.addImage(image);

                                   }

                            }else {

                                   image.setDisplayOrder(1);

                                  imageService.addImage(image);

                            }

                     }

              }

       }

4.HTML代碼

<div class="trd pic add">

      <!-- enctype="multipart/form-data"是圖片上傳的基礎,必須有 -->

    <form id="fm" name="fm" enctype="multipart/form-data" method="post">

       <div class="namezone">輪播圖新增</div>

       <div class="tablezoneclearfix">

           <div class="left box">請添加圖片</div>

           <div class="left box">

               <div class="imageBoxclearfix">

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

                   <span class="red">圖片需處理過</span>

               </div>

           </div>

           <div class="left boxbtn">

                展現順序

               <select name="order" id="order">

                   <option value="1">1</option>

                   <option value="2">2</option>

                   <option value="3">3</option>

                   <option value="4">4</option>

               </select>

               <select name="type" id="type">

                   <option value="電腦">電腦</option>

                   <option value="手機">手機</option>

               </select>

               <input type="button" class="button" value="保存" id="save"/>

               <input type="button" class="button" value="返回" id="back" onclick="history.go(-1)"/>

           </div>

       </div>

    </form>

</div>

5.js代碼

var addPic = {

    //點擊保存向後臺發送保存的數據

    save :function (userName) {

        $("#save").click(function () {

            $.ajax({

                type:"POST",

                url:"/HuaMuWebsite/imageManage/addImage?uploader="+userName,

                data:new FormData($("#fm")[0]),//序列化表單值

                async:false,

                contentType:false,//必須有

                processData:false,//必須有

                error:function(request) {

                    alert("請求出錯!");

                },

                success:function() {

$(window.parent.document).find("#iframe").attr("src",window.location.href="/HuaMuWebsite/admin/src/sliderCtrl.html?userName="+userName);

                }

            });

        })

    }

};


$(function () {

    var userName=window.location.href;

       var aa=userName.indexOf("=");

       if( aa == -1)

             return"";

       userName=userName.substring(aa+1);

       addPic.save(userName);

});

注意:contentType: false,
          processData: false,

這兩個參數是必須的。兩者缺乏任何一個都會報錯。

ajax方法參數老是記不住,在此順便將ajax參數整理以下:

1)url: 要求爲String類型的參數,(默認爲當前頁地址)發送請求的地址

2)type: 要求爲String類型的參數,請求方式(post或get)默認爲get。注意其餘http請求方法,例如put和delete也可使用,但僅部分瀏覽器支持。

3)async同步仍是異步要求爲Boolean類型的參數,默認設置爲true,全部請求均爲異步請求。若是須要發送同步請求,請將此選項設置爲false。注意,同步請求將鎖住瀏覽器,用戶其餘操做必須等待請求完成才能夠執行。

4)cache要求爲Boolean類型的參數,默認爲true(當dataType爲script時,默認爲false),設置爲false將不會從瀏覽器緩存中加載請求信息

5)data:要求爲Object或String類型的參數,要發送到服務器的數據。若是已經不是字符串,將自動轉換爲字符串格式。get請求中將附加在url後。防止這種自動轉換,能夠查看下邊的processData選項。對象必須爲key/value鍵值對格式,例如{key1:"value1",key2:"value2"}轉換爲&key1=value1&key2=value2。若是是數組,JQuery將自動爲不一樣值對應同一個名稱。例如{key:["value1","value2"]}轉換爲&key=value1&key=value2。

6)dataType要求爲String類型的參數,預期服務器返回的數據類型。若是不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,並做爲回調函數參數傳遞。可用的類型以下:
xml
:返回XML文檔,可用JQuery處理。
html
:返回純文本HTML信息;包含的script標籤會在插入DOM時執行。
script
:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。注意在遠程請求時(不在同一個域下),全部post請求都將轉爲get請求。
json
:返回JSON數據。
jsonp
:JSONP格式。使用JSONP形式調用函數時,例如myurl?callback=?,JQuery將自動替換後一個「?」爲正確的函數名,以執行回調函數。
text
:返回純文本字符串。

7)success要求爲Function類型的參數,請求成功後調用的回調函數,有兩個參數。
        
①由服務器返回,並根據dataType參數進行處理後的數據。
        
②描述狀態的字符串。
        function(data, textStatus){

           //data多是xmlDoc、jsonObj、html、text等等
           this;  //
調用本次ajax請求時傳遞的options參數
         }

8)error:要求爲Function類型的參數,請求失敗時被調用的函數。該函數有3個參數,即XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。ajax事件函數以下:
       function(XMLHttpRequest,textStatus, errorThrown){

          //一般狀況下textStatus和errorThrown只有其中一個包含信息
         this;   //
調用本次ajax請求時傳遞的options參數
       }

9)contentType要求爲Boolean類型的參數,當發送信息至服務器時,內容編碼類型默認爲"application/x-www-form-urlencoded"。該默認值適合大多數應用場合。

10)processData要求爲Boolean類型的參數,默認爲true。默認狀況下,發送的數據將被轉換爲對象(從技術角度來說並不是字符串)以配合默認內容類型"application/x-www-form-urlencoded"。若是要發送DOM樹信息或者其餘不但願轉換的信息,請設置爲false。

11)jsonp要求爲String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數裏的"callback"部分,例如{jsonp:'onJsonPLoad'}會致使將"onJsonPLoad=?"傳給服務器。

12)username要求爲String類型的參數,用於響應HTTP訪問認證請求的用戶名

13)password要求爲String類型的參數,用於響應HTTP訪問認證請求的密碼

14)ifModified要求爲Boolean類型的參數,默認爲false。僅在服務器數據改變時獲取新數據。服務器數據改變判斷的依據是Last-Modified頭信息。默認值是false,即忽略頭信息。

15)scriptCharset要求爲String類型的參數,只有當請求時dataType爲"jsonp"或者"script",而且type是GET時纔會用於強制修改字符集(charset)。一般在本地和遠程的內容編碼不一樣時使用。

16)dataFilter要求爲Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
           function(data, type){

               //返回處理後的數據
               return data;

           }

17)timeout要求爲Number類型的參數,設置請求超時時間(毫秒)。此設置將覆蓋$.ajaxSetup()方法的全局設置。

18)global要求爲Boolean類型的參數,默認爲true。表示是否觸發全局ajax事件。設置爲false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用於控制各類ajax事件。

19)beforeSend要求爲Function類型的參數,發送請求前能夠修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中若是返回false能夠取消本次ajax請求。XMLHttpRequest對象是唯一的參數。
           function(XMLHttpRequest){

              this;   //調用本次ajax請求時傳遞的options參數
           }

20)complete要求爲Function類型的參數,請求完成後調用的回調函數(請求成功或失敗時均調用)。參數:XMLHttpRequest對象和一個描述成功請求類型的字符串。
         function(XMLHttpRequest, textStatus){

            this;    //調用本次ajax請求時傳遞的options參數           }

相關文章
相關標籤/搜索