ajax的再次封裝!


js的動態加載、緩存、更新以及復用 系列有點卡文,放心會繼續的。先來點更基礎的,為js的加載做點鋪墊。

 

  jQuery的ajax本來就很方便了,為啥還要在進一步的封裝呢?這個首先要看項目的具體需求了,如果覺得不需要,那么完全可以直接用jQuery提供的各種ajax的方法。如果像我似地,感覺不太方便的話,那么完全可以按照自己的想法和需求來再次封裝一下。

 

  需求:

  1、調用的時候更加的簡單。

  2、可以靈活的做各種設置和變化。

  3、可以滿足一些通用的需求。比如出錯的時候給出提示。

 

  項目現狀:

    做ajax請求的時候,會有一個加載的動畫,在ajax發起的時候要自動開始,加載完畢之后要自動停止。出錯了也要自動停止,並且給出錯誤提示。請求的URL比較固定,按照增刪改查來分類。要可以跨域,也可以不跨域。需要靈活的進行切換。ajax獲得數據的同時,還會附帶一段調試信息,需要顯示出來。有專門的處理函數,但是需要調用。

 

  實現:

    直接上代碼吧。

//對ajax的封裝
Nature.Ajax = function (ajax) {
    //最基礎的一層封裝
   
        //定義默認值
        var defaultInfo = {
            type: "GET",                        //訪問方式:如果dataPata不為空,自動設置為POST;如果為空設置為GET。
            dataType: Nature.sendDataType,      //數據類型:JSON、JSONP、text。由配置信息來搞定,便於靈活設置
            cache: true,                        //是否緩存,默認緩存
            xhrFields: {
                //允許跨域訪問時添加cookie。cors跨域的時候需要設置
                withCredentials: true
            },
            urlPata: {},//url后面的參數。一定會加在url后面,不會加到form里。
            formPata: {},//表單里的參數。如果dataType是JSON,一定加在form里,不會加在url后面;如果dataType是JSONP的話,只能加在url后面。

            //url:  //依靠上層指定

            //timeout: 2000,
            error: function() {
            },  //如果出錯,停止加載動畫,給出提示。也可以增加自己的處理程序

            success: function() {
            } //成功后顯示debug信息。也可以增加自己的處理程序
        };

        //補全ajaxInfo
        if (typeof ajaxInfo.dataType == "undefined") {
            ajaxInfo.dataType = defaultInfo.dataType;
        }
        
        if (typeof ajaxInfo.formPata == "undefined") {
            ajaxInfo.type = "GET";
        } else {
            if (ajaxInfo.dataType == "JSON") {
                ajaxInfo.type = "POST";
            } else {    //get或者jsonp
                ajaxInfo.type = "POST";
            }
            ajaxInfo.data = ajaxInfo.formPata;

        }

        if (typeof ajaxInfo.cache == "undefined") {
            ajaxInfo.cache = defaultInfo.cache;
        }
   


        //處理URL
        if (typeof ajaxInfo.urlPata != "undefined") {
            var tmpUrlPara = "";
            var para = ajaxInfo.urlPata;
            for (var key in para) {
                tmpUrlPara += "&" + key + "=" + para[key];
            }

            if (ajaxInfo.url.indexOf('?') >= 0) {
                //原地址有參數,直接加
                ajaxInfo.url += tmpUrlPara;
            } else {
                //原地址沒有參數,變成?再加
                ajaxInfo.url += tmpUrlPara.replace('&', '?');
            }
        }

        //開始執行ajax
        $.ajax({
            type: ajaxInfo.type,
            dataType: ajaxInfo.dataType,
            cache: ajaxInfo.cache,
            xhrFields: {
                //允許跨域訪問時添加cookie
                withCredentials: true
            },
            url: ajaxInfo.url,  
            data: ajaxInfo.data,
            //timeout: 2000,
            error: function() { //訪問失敗,自動停止加載動畫,並且給出提示
                alert("提交" + ajaxInfo.title + "的時候發生錯誤!");
                if (typeof top.spinStop != "undefined")
                    top.spinStop();
                if (typeof ajaxInfo.error == "function") ajaxInfo.error();
            },

            success: function (data) {
                if (typeof(parent.DebugSet) != "undefined")
                    parent.DebugSet(data.debug);  //調用顯示調試信息的函數。
                
                if (typeof (ajaxInfo.ctrlId) == "undefined")
                    ajaxInfo.success(data);
                else {
                    ajaxInfo.success(ajaxInfo.ctrlId, data);
                }

            }
        });
    

   

};

 

    這是最底層的封裝,然后是根據URL的封裝,其實就是避免在代碼里到處寫URL的問題。

 1 Nature.Data.MetaData = function () {
 2 
 3     var ajax = Nature.Ajax;//簡化一下
 4 
 5 
 6     /*獲取頁面視圖的元數據*/
 7     this.ajaxGetMeta = function (ajaxData) {
 8 
 9         ajaxData.url = Nature.resourceUrl + "/MetaData/GetMeta.ashx";
10         ajaxData.cache = false;
11         
12         ajax(ajaxData);
13     };
14 
15     
16 
17 }
18 
19 Nature.Data.CusData = function () {
20 
21     var ajax = Nature.Ajax;
22     
23   34     //獲取客戶數據
35     this.ajaxGetData = function(ajaxData) {
36 
37         //增刪改查服務的網址
38         var url = Nature.resourceUrl;
39         if (typeof ajaxData.url == "undefined")
40             url += "/Data/GetData.ashx";
41         else
42             url += ajaxData.url;
43 
44         ajaxData.url = url;
45         ajaxData.cache = false;
46 
47         ajax(ajaxData);
48         
49     };
50     
51     /*刪除數據*/
52     this.ajaxDeleteData = function (ajaxData) {
53         var url = Nature.resourceUrl;
54         
55         if (typeof ajaxData.url == "undefined")
56             url += "/Data/GetData.ashx";
57         else
58             url += ajaxData.url;
59         
60         ajaxData.url = url;
61         ajaxData.cache = false;
62 
63         ajax(ajaxData);
64     };
65     
66 
67 }

 

    這個是按照增刪改查的URL地址來定的幾個函數。主要目的就是處理具體的URL,避免代碼里面到處都是URL的混亂問題。

    最后就是具體應用的地方了。

 1  var load = new Nature.Data.MetaDate();
 2 
 3   load.ajaxGetMeta({
 4             urlPata: { action: "tree", mdid: 0, dbid: dataBaseId, ProjectID: projectId, cacheKey: 0 },
 5             title: "獲取XXX",
 6             success: function (msg) {
 7                 
 8                 if (typeof top.__cache == "undefined")
 9                     top.__cache = {};/* 開辟緩存空間 */
10                  
11                 top.__cache.treeMeta = msg.data;
12                 
13                 create2(msg.data);
14             }
15         });

 

  這樣調用起來就比較簡單了,避免了一些常用且固定的參數的設置,比如type、dataType、cache、url等。可能有些童鞋會想了,不是有$.get和$.post了嗎,比你的更簡潔吧,你還自己折騰啥!

  $.get和$.post確實更簡潔,但是不夠靈活,比如cache的設置,有的時候需要緩存,有的時候不需要緩存。再比如type,有的頁面需要跨域,有的地方不需要跨域。有的時候要根據項目來統一設置(切換)。所以我自己折騰了一下。

 

  詳細說明:

  默認參數里的幾個屬性的含義。

  1、title。ajax有可能出錯,出錯了就應該有個提示。但是一個頁面往往有多個ajax,到底是哪個出錯了?所以我設置了一個title的屬性,在error的時候 alert("提交" + ajaxInfo.title + "的時候發生錯誤!");這樣就比較清晰了,至少按照title的屬性值來find一下,可以快速定位。

 

  2、urlPata和formPata。jQuery的ajax只有一個data的屬性。當get的時候,會把data放到URL里面,傳遞給服務器;當POST的時候,會把data放在form里面,提交給服務器。這個似乎挺好,但是在post的時候,我需要明確的把一些參數放在URL里面,一些參數放在form里面。這個就不能都放在data里面,我還得自己去拼接URL。麻煩還愛出錯。所以我就分成了兩個屬性urlPata和formPata。

    urlPata肯定會出現在URL里面。formPata就需要根據情況而定了。JSON的時候會放在form里面,JSONP的時候就只能放在URL里面了。

 

  3、xhrFields。這個就涉及到HTML5.0里面對post跨域的支持問題了。一般提到跨域,想到的都是JSONP,但是JSONP是偽裝成<script>來實現的跨域,由於js並不支持post,所以導致無法實現post的跨域提交。現在HTML5.0解決了這個問題,就是cors。我也是最近幾天才弄明白這個。后來發現jQuery也是支持cors的。jQUery.support.cors = true; 這樣就可以開啟cors。然后在測試的時候發現個問題,出於安全考慮,默認情況下cors的跨域是不會附帶cookie信息的,需要手動設置。於是就出現了xhrFields這一段。當然要完全實現cors,服務器端也需要做相應的設置,這個會在我的《細說跨域那點事》里面有詳細的說明。

 

  4、error。ajax訪問,難免會出現點小意外,有的是服務器返回的值有問題,有時候是服務器報錯了。那么要怎么辦呢?於是就出現了這個error的統一處理函數。在這里首先會根據title屬性給出一個提示,告訴用戶,訪問出錯了。然后會把加載的動畫提示給停掉。一開始在出錯的時候沒有去停止加載動畫,好多用戶就更我說,你那個頁面,轉呀轉呀,轉了n就都沒反應。所以我就加上了這段。

 

  5、success。成功之后,調用顯示調試信息的函數,把調試信息給顯示出來。便於調試和優化。

 

  6、defaultInfo。首先以傳遞過來的ajaxInfo為准,如果有了就按照ajaxInfo的來,如果沒有指定,就使用defaultInfo提供的對應屬性來賦值。就是一個缺省值的作用。

 

  折騰的好處:

  一開始error里面,沒有alert的提示,很不可思議吧,但是確實是沒有。后來想想還是加上吧,那么我改一個地方就ok了,不需要到處都去改。后來又加上了停止加載動畫的功能,現在想想,是不是也要把顯示調試信息的給加上呢?有些錯誤也是會返回調試信息的呀。如果加的話,也是只需要改一個地方就ok了。

 

  以前不知道cors,學會cors之后發現要附帶cookie的話,還要加上xhrFields,那好吧,就一個地方加上就行了,也不需要到處去改。

 

  總之,當變化發生的時候,我只需要改一個地方就ok了,我不需要到處去改,還容易漏掉某某。

 

ps:

這里跳過了一個步驟,就是“緩存”。不是ajax帶的cache,而是類似於本地儲存(Local Storage)的東東。這個以后會詳細說明。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM