http.js(简化ajax api设计并为请求增加拦截过滤器)


1. 简化API
2. 实现拦截过滤器
3. 设置全局请求参数
http://www.oschina.net/code/snippet_698737_38073#56274
可在这里查看更新:https://gist.github.com/lenbo-ma/0213bfea8e3f08ff8d66
相关博文:http://mlongbo.com/http-js-zai-ajaxdan-ye-mian-zhong-de-ying-yong/

$http.global("token","abcd321");//页面中的每个ajax请求都将发送这个参数 $http.intercept("json", function (res) { if (res.code === 3) { alert("需要重新登录哦"); return false; } else if (res.code === 401) { alert("未授权的查询"); return false; } return true; }); $http.get("/api/user").push("id", 110).type("json").send(function (res) { //这个请求会被拦截器过滤 if (res.code === 1) { alert("查询到了"+res.datum.name+"的信息~"); console.log(res.datum); } else { alert(res.message); } }, function (err) { alert("查询失败了额"); console.error(err); }); $http.get("/tmpl/menu.html").type("html").send(function (html) { //这个请求不会被拦截器过滤 console.log(html); });
/**
 * @author Longbo Ma
 */
(function($) {
        var _Http = {},
            globalData = {}, //全局数据,请求时会发送
            interceptors = [] //全局拦截器;

        /**
         * 合并数据
         * @param global
         * @param data
         * @returns {*}
         */
        function merge(global, data) {

            if (!data) return copy(global, {});

            var result = copy(global, {});

            return copy(data, result);
        }

        /**
         * copy json对象数据
         * @param s 源对象
         * @param t 目的对象
         * @returns {*}
         */
        function copy(s, t) {
            for (var key in s) {
                t[key] = s[key];
            }
            return t;
        }


        /**
         * 将普通数组转化为json对象,json key为数组项值
         * 方便判断
         * @param arr
         * @returns {{}}
         */
        function toJsonArr(arr) {
            var json = {};

            for (var i = 0, total = arr.length; i < total; i++) {
                json[arr[i]] = "";
            }

            return json;
        }

        /**
         * 检测json数组中是否包含某个值
         * @param jsonArr 该值必须是从toJsonArr函数得来的
         * @param val 要检查的值
         * @returns {*|boolean} 结果
         */
        function contain(jsonArr, val) {
            return jsonArr.hasOwnProperty(val);
        }

        /**
         * Ajax请求对象
         * @param method 请求类型
         * @param url 请求链接
         * @param data 发送的数据  json对象or拼接的string数据
         * @constructor
         */
        var Request = function(method, url, data) {
            this.method = method;
            this.url = url;
            this.data = data || {};
            this.headers = [];
        };

        /**
         * 设置响应数据类型
         * @param type 字符串"json"/"xml"等
         * @returns {Request}
         */
        Request.prototype.type = function(type) {
            this.type = type;
            return this;
        };

        /**
         * 设置发送的数据,将覆盖已设置的数据
         * @param data  json对象or拼接的string数据
         * @returns {Request}
         */
        Request.prototype.data = function(data) {
            this.data = data;
            return this;
        };

        /**
         * 设置新发送的数据
         * @param key 参数名/json object
         * @param value 参数值
         * @returns {Request}
         */
        Request.prototype.push = function(key, value) {
            if (!key || !value) return;

            try {
                JSON.stringify(key);
                copy(key, this.data);
            } catch (err) {
                this.data[key] = value;
            }
            return this;
        };

        /**
         * set headers
         * @param  {[json object]} headers
         * @return {[Request]}   
         */
        Request.prototype.headers = function(headers) {
            this.headers = headers;
            return this;
        };

        /**
         * push header item
         * @param  {[String,JSON]} key  
         * @param  {[String,null]} value
         * @return {[Request]} 
         */
        Request.prototype.header = function(key, value) {
            if (!key || !value) return;

            try {
                JSON.stringify(key);
                copy(key, this.headers);
            } catch (err) {
                this.headers[key] = value;
            }
            return this;
        };

        /**
         * execute interceptors
         * @param  {[type]} res [description]
         * @return {[type]}     [description]
         */
        Request.prototype.execuInters = function(res) {
            //执行拦截器
            for (var i = 0, total = interceptors.length; i < total; i++) {
                //先判断是否是所要拦截的数据响应类型
                if (!contain(interceptors[i].type, self.type)) {
                    continue;
                }

                var invoke = interceptors[i].fn(res); //执行拦截器
                //检查结果,决定是否继续执行其他拦截器
                if (invoke !== undefined && !invoke) {
                    return false;
                }
            }
            return true;
        };

        /**
         * 发送请求
         * @param success 成功响应回调函数
         * @param error 错误处理回调函数
         */
        Request.prototype.send = function(success, error) {
            var self = this;
            var param = {
                url: this.url,
                type: this.method
            };

            //设置响应数据类型
            if (this.type) {
                param.dataType = this.type;
            }

            //设置发送数据
            if (this.data && typeof this.data !== 'function') {
                param.data = this.data;
            }

            //set headers
            if (this.headers && typeof this.headers !== 'function' && JSON.stringify(this.headers).length > 2)) {
            param.headers = this.headers;
        }

        //设置成功响应回调函数
        if (success && typeof success === 'function') {
            param.success = function(res) {
                if (self.execuInters(res)) { //执行回调
                    success(res);
                }
            };
        }

        //设置错误响应回调函数
        if (error && typeof error === 'function') {
            param.error = function(err) {
                //正确的请求响应
                if (err.status === 200 && err.statusText === "OK") {
                    var response = err.responseText;

                    //如果是json数据,则转化为json对象
                    try {
                        response = JSON.parse(response);
                    } catch (parseError) {
                        response = err.responseText;
                    }

                    if (self.execuInters(response)) { //执行回调
                        success(response);
                    }
                } else {
                    error(err);
                }
            };
        }

        $.ajax(param);
    };

    /**
     * 发送POST请求
     * @param url 请求地址
     * @param data 请求数据,json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.post = function(url, data) {
        return new Request("POST", url, merge(globalData, data));
    };

    /**
     * 发送PUT请求
     * @param url 请求地址
     * @param data 请求数据,json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.put = function(url, data) {
        return new Request("PUT", url, merge(globalData, data));
    };

    /**
     * 发送GET请求
     * @param url 请求地址
     * @param data 请求数据,json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.get = function(url, data) {
        return new Request("GET", url, merge(globalData, data));
    };

    /**
     * 发送DELETE请求
     * @param url 请求地址
     * @param data 请求数据,json或拼接的字符串
     * @returns {Request} 请求对象
     */
    _Http.del = function(url, data) {
        return new Request("DELETE", url, merge(globalData, data));
    };

    /**
     * 设置全局请求值
     * @param name string or jsonObject
     * @param value
     */
    _Http.global = function(name, value) {
        if (!name || !value) return;

        try {
            JSON.stringify(name);
            copy(name, globalData);
        } catch (err) {
            globalData[name] = value;
        }

        return _Http;
    };

    /**
     * 新增一个拦截器
     * @param type
     * @param fn
     */
    _Http.intercept = function(type, fn) {
        //type参数可以为单个字符串或数组
        if (typeof type === 'string') {
            type = [type]; //转化为数组
        }

        interceptors.push({
            type: toJsonArr(type),
            fn: fn
        });

        return _Http;
    };

    this.$http = _Http;
})(jQuery);

 

posted @ 2016-08-09 13:21  五艺  阅读(1174)  评论(0)    收藏  举报