​原生JavaScript模拟jquery的ajax的部分功能(含jsonp)

有时候,我们会用到jquery的ajax方法,但是又不想或没必要用jquery的其他功能,我们就可以用以下代码来替代:

function ajax (params) {
    params = params || {};
    params.data = params.data || {};
    var json = params.jsonp ? jsonp(params) : json(params);
    // ajax请求
    function json(params) {
        params.type = (params.type || 'GET').toUpperCase();
        params.data = formatParams(params.data);
        var xhr = null;

        // 实例化XMLHttpRequest对象
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else {
            // IE6及其以下版本
            xhr = new ActiveXObjcet('Microsoft.XMLHTTP');
        }
        // 监听事件
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                var status = xhr.status;
                if (status >= 200 && status < 300) {
                    var response = '';
                    var type = xhr.getResponseHeader('Content-type');
                    if (type.indexOf('xml') !== -1 && xhr.responseXML) {
                        response = xhr.responseXML; //Document对象响应
                    } else if (type === 'application/json') {
                        response = JSON.parse(xhr.responseText); //JSON响应
                    } else {
                        response = xhr.responseText; //字符串响应
                    }
                    params.success && params.success(response);
                } else {
                    params.error && params.error(status);
                }
            }
        };

        // 连接和传输数据
        if (params.type == 'GET') {
            xhr.open(params.type, params.url + '?' + params.data, params.async && typeof(params.async) == 'boolean' ? !params.async : true);
            xhr.send(null);
        } else {
            xhr.open(params.type, params.url, params.async && typeof(params.async) == 'boolean' ? !params.async : true);
            //设置提交时的内容类型
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
            xhr.send(params.data);
        }
    }

    // jsonp请求
    function jsonp(params) {
        //创建script标签并加入到页面中
        var callbackName = params.jsonp;
        // 设置传递给后台的回调参数名
        params.data[callbackName] = params.jsonpCallback;
        var data = formatParams(params.data);
        var script = document.createElement('script');
        if (params.async === true) {
            script.setAttribute("async", "async");
        }
        window.onload=function(){
            var scripts = document.getElementsByTagName('script');
            var lastScript = scripts[scripts.length - 1];
            lastScript.parentNode.insertBefore(script, lastScript.nextSibling);

            //创建jsonp回调函数
            window[params.jsonpCallback] = function (json) {
                script.parentNode.removeChild(script);
                clearTimeout(script.timer);
                window[params.jsonpCallback] = null;
                params.success && params.success(json);
            };

            //发送请求
            if (params.url.indexOf('?') > -1) {
                script.src = params.url + '&' + data;
            } else {
                script.src = params.url + '?' + data;
            }
            //超时处理
            if (params.time) {
                script.timer = setTimeout(function () {
                    window[callbackName] = null;
                    script.parentNode.removeChild(script);
                    params.error && params.error({
                        message: '超时'
                    });
                }, time);
            }
        }

    };
    //格式化参数
    function formatParams(data) {
        var arr = [];
        for (var name in data) {
            arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
        }
        // 添加一个随机数,防止缓存
        arr.push('_=' + new Date().getTime());
        return arr.join('&');
    }


}

//调用

ajax({
    url: 'url',
    type: 'get',//post
    async: true,//false
    dataType: 'jsonp',//json
    jsonp: 'callback',//不是jsonp就不填
    jsonpCallback: 'jsonpCallback',//不是jsonp就不填
    contentType: 'application/json; charset=utf-8',//不是jsonp就不填
    error: function (e) {
    },
    success: function (data) {
       
    }
});

以上也有不严谨的地方 比如判断传参环节、同异步环节等都可以再优化 只是大部分场景以上还是适用的 不适用就再改改(造轮子真难。。。)

代码参考:http://www.jb51.net/article/104873.htm 

未经允许不得转载:前端撸码笔记 » ​原生JavaScript模拟jquery的ajax的部分功能(含jsonp)

上一篇:

下一篇: