【网络】仿JQ之AJAX请求

总体思路

  • 兼容IE写法
  • 初始化发送请求open
  • 通过onreadystatechange监听readyState
  • 设置请求头(若有POST请求,GE请求T不用设置)
  • 发送请求
  • 请求超时监视

配置项

url:接口地址
type:请求方式GET/POST
dataType: XML/TEXT/JSON/JSONP
data:发送到服务器的数据(非跨域请求)
jsonp:使用JSONP形式调用函数,如index.php?cb=xxx 后端获取GET请求的xxx值
jsonpCallback:为JSONP指定一个回调函数名,这个值将用来取代JQuery自动生成的随机函数名
async:默认值true,所有请求均为异步请求。如需发送同步请求,设置该选项为false
success:请求成功后执行的回调函数
error:请求失败的执行的回调函数
complete:请求完成后执行的回调函数(无论请求成功还是失败)
timeout:设置请求超时时间,默认30s

整体代码

var $ = (function(){
    function doAjax(opt){
        var url = opt.url,
            type = opt.type,
            dataType = opt.dataType || 'JSON',
            data = opt.data,
            jsonp = opt.jsonp || 'cb',
            jsonpCallback = opt.jsonpCallback || 'jQuery' + randomNum() + '_' + new Date().getTime(), //JSONP回调函数
            async = '' + opt.async === 'false' ? false : true,  //异步模式默认开启
            success = opt.success,
            timeout = opt.timeout || 30000,
            complete = opt.complete || function(){}, //无论请求成功或失败都执行complete回调函数
            error = function(){
                throw new Error('HTTP请求失败');
            },
            xhr = window.XMLHttpRequest ? new XMLHttpRequest()
                                        : new ActiveXObject('Mirosoft.XMLHTTP')
            if(!xhr){
                console.log('XMLHttpRequest对象不存在');
            }
        var t = null;
        //JSONP跨域请求
        if(dataType.toUpperCase() === 'JSONP'){
            var oScript = document.createElement('script');
                oScript.src = url.indexOf('?') === -1  
                    ? url + '?' + jsonp + '=' + jsonpCallback  //普通请求
                    : url + '&' + jsonp + '=' + jsonpCallback; //GET请求 PHP $_GET()方法只会获取最后一个&中的参数


            window[jsonpCallback] = function(data){
                success(data);
            }
            document.body.appendChild(oScript); //把script标签加入html并执行
            document.body.removeChild(oScript); //执行完后立刻删除script
             
            return;
        }
        //实时监听readyState状态
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                if(typeof success === 'function'){
                    // 返回三种数据类型:JSON、TEXT、XML
                    switch(dataType.toUpperCase()){
                        case 'JSON':
                        success(JSON.parse(xhr.responseText));
                        break;
                        case 'TEXT':
                        success(xhr.responseText);
                        break;
                        case 'XML':
                        success(xhr.responseXML);
                        break;
                    }
                }
                complete();
                clearTimeout(t); //请求成功清除超时定时器
                t = null; //初始化定时器
                xhr = null; //初始化xhr对象 
            }
        }

        xhr.open(type,url,async); //发送HTTP请求
        type === 'POST' && xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded'); //POST请求必须设置请求头
        xhr.send(type === 'GET' ? null : formatData(data));
        //请求超时定时器
        t = setTimeout(function(){
            complete();
            xhr.abort();
            error(); //弹出错误
            clearTimeout(t);
            t = null;
            xhr = null;
            throw new ('本次请求已超时,API地址' + url);
        },timeout)

    }

    function formatData(data){
        var list = '';
        for(var name in data){
            list += name + '=' + data[name] + '&';
        }
        list.replace(/&$/, '');  //去除字符串最后的一位&
        return list;
    }

    function randomNum(){
        var num = '';
        for(var i = 0; i < 20; i++){
            num += Math.floor(Math.random()*10);
        }
        return num;
    }
    return {
        ajax: function(opt){
            doAjax(opt);
        },
        get: function(url,callback){
            doAjax({
                url: url,
                type: 'GET',
                success: callback
            });
        },
        post: function(url,data,callback){
            doAjax({
                url: url,
                type: 'POST',
                data: data,
                success: callback
            });
        }
    }
})();
posted @ 2021-08-05 11:40  razzh  阅读(65)  评论(0)    收藏  举报