js封裝 Ajax ——常用工具函式

Linda0821發表於2019-02-16

在前端開發中,ajax的重要性不言而喻,所以我開始試著封裝自己專屬ajax
1.常規封裝

/* 封裝ajax函式
 * @param {string}opt.method http連線的方式,包括POST和GET兩種方式
 * @param {string}opt.url 傳送請求的url
 * @param {boolean}opt.async 是否為非同步請求,true為非同步的,false為同步的
 * @param {object}opt.data 傳送的引數,格式為物件型別
 * @param {function}opt.success ajax傳送並接收成功呼叫的回撥函式
 */
/*1常規封裝*/
function ajax(opt) {
    opt = opt || {};
    opt.method = opt.method.toUpperCase() || "GET"; //GET:用"GET"方式傳送資料,只能256KB;POST:用"POST"方式傳送資料,可以大到4MB
    opt.url = opt.url || "";
    opt.async = opt.async || true; //同步非同步
    opt.dataType = opt.dataType || "text"; //所傳的數的資料型別
    opt.contentType = opt.contentType || "application/x-www-form-urlencoded; charset=utf-8"; //預設表單格式 opt.dataType=`json`
    opt.data = opt.data || null;


    var xmlHttp = getXmlHttp(); //獲取XML 物件

    var postData = getAjaxParama(opt.data); //data

    if (opt.contentType === "application/json;charset=utf-8" && opt.dataType === "json") {
        postData = JSON.stringify(opt.data); //轉化為字串
    }

    if (opt.method === `POST`) {
        xmlHttp.open(opt.method, opt.url, opt.async);
        xmlHttp.setRequestHeader(`Content-Type`, opt.contentType); //而POST請求需要設定請求頭,用來傳遞引數

    } else if (opt.method === `GET`) {
        postData = opt.url.indexOf("?") >= 0 ? "&" + postData : "?" + postData; //GET請求,引數是拼接到url上面;
        xmlHttp.open(opt.method, opt.url + postData, opt.async);
        postData = null; //重置引數
    }
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4) {
            var status = xmlHttp.status;
            if (status >= 200 && status < 300) {
                opt.success && opt.success(xmlHttp.responseText);
            } else {
                opt.error && opt.error(status);
            }
        }
    };

    xmlHttp.send(postData);

    function getXmlHttp() {
        var obj = null;
        //非IE瀏覽器建立XmlHttpRequest物件
        if (window.XMLHttpRequest) obj = new XMLHttpRequest();

        //IE瀏覽器建立XmlHttpRequest物件
        if (window.ActiveXObject) {
            try {
                obj = new ActiveXObject(`Microsoft.XMLHTTP`);
            } catch (e) {
                try {
                    obj = new ActiveXObject("msxml2.XMLHTTP");
                } catch (ex) {}
            }
        }
        return obj;

    }

    function getAjaxParama(data) {
        var params = [];

        for (var key in data) {
            params.push(encodeURIComponent(key) + `=` + encodeURIComponent(data[key]));
        }
        return params.join(`&`); //新增&字串

    }

}

2.自定義封裝

/**
 * [ajax封裝ajax函式]
 * @Author   Linada
 * @DateTime 2017-12-19T16:16:32+0800
 * @param {string}  opt.method [http連線的方式,包括POST和GET兩種方式]
 * @param {string}  opt.url [傳送請求的url]
 * @param {boolean} opt.async [是否為非同步請求,true為非同步的,false為同步的]
 * @param {object}  opt.data [傳送的引數,格式為物件型別]
 * @param {function}  opt.success [ajax傳送並接收成功呼叫的回撥函式]
 */

;(function (undefined) {
    "use strict"
    var _global;
    var umeAjax = {
        ajax: function (opt) {
            opt = opt || {};
            opt.method = opt.method.toUpperCase() || "GET"; //GET:用"GET"方式傳送資料,只能256KB;POST:用"POST"方式傳送資料,可以大到4MB
            opt.url = opt.url || "";
            opt.async = opt.async || true; //同步非同步
            opt.dataType = opt.dataType || "text"; //所傳的數的資料型別
            opt.contentType = opt.contentType || "application/x-www-form-urlencoded; charset=utf-8"; //預設表單格式 opt.dataType=`json`
            opt.data = opt.data || null;


            var xmlHttp = getXmlHttp(); //獲取XML 物件

            var postData = getAjaxParama(opt.data); //data

            if (opt.contentType === "application/json;charset=utf-8" && opt.dataType === "json") {
                postData = JSON.stringify(opt.data); //轉化為字串
            }

            if (opt.method === `POST`) {
                xmlHttp.open(opt.method, opt.url, opt.async);
                xmlHttp.setRequestHeader(`Content-Type`, opt.contentType); //而POST請求需要設定請求頭,用來傳遞引數

            } else if (opt.method === `GET`) {
                postData = opt.url.indexOf("?") >= 0 ? "&" + postData : "?" + postData; //GET請求,引數是拼接到url上面;
                xmlHttp.open(opt.method, opt.url + postData, opt.async);
                postData = null; //重置引數
            }
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState == 4) {
                    var status = xmlHttp.status;
                    if (status >= 200 && status < 300) {
                        opt.success && opt.success(xmlHttp.responseText);
                    } else {
                        opt.error && opt.error(status);
                    }
                }
            };

            xmlHttp.send(postData);
        },


    }

    function getXmlHttp() {
        var obj = null;
        //非IE瀏覽器建立XmlHttpRequest物件
        if (window.XMLHttpRequest) obj = new XMLHttpRequest();

        //IE瀏覽器建立XmlHttpRequest物件
        if (window.ActiveXObject) {
            try {
                obj = new ActiveXObject(`Microsoft.XMLHTTP`);
            } catch (e) {
                try {
                    obj = new ActiveXObject("msxml2.XMLHTTP");
                } catch (ex) {
                }
            }
        }
        return obj;

    }


    function getAjaxParama(data) {
        var params = [];

        for (var key in data) {
            params.push(encodeURIComponent(key) + `=` + encodeURIComponent(data[key]));
        }
        return params.join(`&`); //新增&字串

    }

    // 最後將外掛物件暴露給全域性物件
    _global = (function () {
        return this || (0, eval)(`this`);
    }());
    if (typeof module !== "undefined" && module.exports) {
        module.exports = umeAjax;
    } else if (typeof define === "function" && define.amd) {
        define(function () {
            return umeAjax;
        });
    } else {
        !(`umeAjax` in _global) && (_global.umeAjax = umeAjax);
    }
}());

3.使用

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>js測試</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/>
    <meta name="description" content="my fortune" />
    <style>        
        html {
            font-size: 24px!important;
            padding-bottom: 0;
        }        
    </style>
</head>
 <body>
    <div id="ajax">
        
    </div>
    <script src="./ajax.js"></script>    
    <script type="text/javascript">
        var country = "US";
        var lan = "en";
        var news_url = "https://contentapi.celltick.com/mediaApi/v1.0/notification";
        ajax({
            method: "GET",
            data: {
                publisherId: "ZTE-Push",
                key: "ZPaP5GSQzmg41tHF0h7Jv0u2SOuH4OM4",
                limit: 10,
                userId: "572776656",
                countryCode: country,
                lanuguage: lan

            },
            url: news_url,
            success: function(response) {
                //console.log(response);
                document.getElementById("ajax").innerHTML=response;
            },
            error: function(e) {
                console.log(e);
            }
        });

    </script>

    <script src="./ajax.fn.js"></script>
    <script type="text/javascript">
        umeAjax.ajax({
            method: "GET",
            data: {
                publisherId: "ZTE-Push",
                key: "ZPaP5GSQzmg41tHF0h7Jv0u2SOuH4OM4",
                limit: 10,
                userId: "572776656",
                countryCode: country,
                lanuguage: lan

            },
            url: news_url,
            success: function(response) {
                console.log("umeAjax: "+response.length);
            },
            error: function(e) {
                console.log(e);
            }
        });

        var getAdUrl = "http://browser.umeweb.com/cn_ume_api/ads/api/request"; //ajax引數

        umeAjax.ajax({
            method: `POST`,
            url: getAdUrl,
            contentType: "application/json;charset=utf-8",
            data:{
                "app": {
                    "sdk_channel": "",
                    "app_id": "",
                    "app_version": "",
                    "app_package": ""
                },
                "addes": [{
                    "ad_type": 2,
                    "impression_num": 3,
                    "ad_slot": 2,
                    "ad_width": 0,
                    "ad_height": 0
                }],
                "device": {
                    "screen_width": 1280,
                    "screen_height": 720,
                    "os_type": 2,
                    "imei": "864783024054476",
                    "device_type": 2,
                    "androidid": "f58d85c248c37836",
                    "model": "HLANOTE1-L",
                    "os_version": "",
                    "hardware": "mt6752",
                    "display": "HLANOTE1-L-V1.0",
                    "total_rom": "3047200",
                    "board": "techain6752_lt_kk",
                    "total_ram": "1961972",
                    "product": "HLANOTE1-L",
                    "manufacturer": "YUSUN",
                    "device": "HLANOTE1-L",
                    "brand": "YUSUN",
                    "mac": "e8:92:a4:99:6f:00"
                },
                "user": {
                    "ip": "115.239.210.20",
                    "uid": "",
                    "imsi": "460016131813183",
                    "networktype": 1,
                    "lang": "zh_CN"
                } 
            },
            dataType: `json`,
            success: function(data) {
                var obj = JSON.parse(data);
                if (obj.retcode == "0" && obj.ads.length > 0) {
                    console.info("廣告API請求成功:"+ JSON.stringify(obj));
                } else {
                    console.info("請求成功,資料異常 :"+ JSON.stringify(obj));
                }
            },
            fail: function(e) {
                console.info("請求錯誤,錯誤資訊:"+e);
            }
        });

    </script>
        
</body> 
</html>

4.擴充
封裝post方式的promise的ajax外掛


/*
*promise
* 用Promise封裝一個post請求的方法
*/
function postJSON(url, data) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        xhr.setRequestHeader("Content-type", "application/json;charset=utf-8");

        xhr.onreadystatechange = function() {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this);
                    //debug_print("ajaxPromise(param) success: " +this.responseText);
                } else {
                    var resJson = {
                        code: this.status,
                        response: this.response
                    };
                    reject(resJson, this);
                }
            }
        };
        xhr.send(JSON.stringify(data));
    });
}

// 用Promise封裝一個get請求的方法,基於ajax
function ajaxPromise(param) {
    return new Promise(function (resolve, reject) {
        $.ajax({
            url: param.url,
            type: `get`,
            data: param.data || ``,
            success: function (data) {
                //console.info(data);
                debug_print("ajaxPromise(param) success: " + JSON.stringify(data));
                resolve(data);
            },
            error: function (error) {
                //console.info(error);
                debug_print("ajaxPromise(param) error: " + JSON.stringify(error));
                reject(error)
            }
        });
    });
}

相關文章