ajax简单封装

本文详细介绍了如何使用JavaScript的AJAX实现HTTP请求,包括数据对象转字符串、GET请求参数处理、超时设置、请求头管理,以及成功和错误回调的处理。通过实例展示了如何配置AJAX请求并控制缓存和异步行为。
摘要由CSDN通过智能技术生成
(function () {
    function ajax(options) {
        //new ajax() //死递归
        return new init(options);
    }
    ajax.prototype = {
        constructor: ajax,
        send: function () {
            //this-->当前的实例
            let {
                method,
                url,
                async,
                data,
                timeout,
                headers,
                success,
                cache,
                error,
                dataType
            } = this.options
            //专门用来发送请求
            //把当前的xhr放到init(ajax)的实例上,方便以后查看
            let xhr = this.xhr = new XMLHttpRequest;

            //1.首先看一下当前的data是对象还是字符串,如果是字符串那就不用处理,如果是对象,那就把它转换成字符串
            //'name=1&age=2'
            //{name:1,age:2}-->'name=1&age=2'
            data = this.handleData();

            //2.查看一下当前是否是get系列请求,如果是的话那就看看data有没有值,如果data有值那就直接拼接到url的后面
            let reg = /^(GET|DELETE|HEAD|OPTIONS)$/i;
            if (data && reg.test(method)) {
                //http://www.baidu.com
                //http://www.baidu.com?sex=0
                url += `${this.hasQuestionMark(url)}${data}`;

                // this.options.url=url;

                data = null; //如果是get请求,在把data使用完成之后就把他赋值为null,这样就不会在send里传递了
            }

            //3.如果是get系列请求,并且cache的值是false,说明不走缓存(在url后面拼接一个时间戳或者随机数)
            if (reg.test(method) && !cache) {
                let num = Math.random();

                url += `${this.hasQuestionMark(url)}_=${num}`;

                // this.options.url=url;
            }

            //4.处理请求超时的时间设置
            if (timeout) {
                xhr.timeout = timeout;
            }

            xhr.open(method, url, async);

            //5.设置请求头(必须在open之后,send之前) headers是一个对象 
            if (headers) {
                for (let key in headers) {
                    if (!headers.hasOwnProperty(key)) {
                        break;
                    }
                    xhr.setRequestHeader(key, encodeURI(headers[key]))
                }
            }

            xhr.onreadystatechange = function () {
                //在这里做响应的处理
                let {
                    readyState,
                    responseText,
                    responseXML,
                    status,
                    statusText,
                    response
                } = xhr;

                if (readyState == 4) {
                    let res = '';
                    if (/^(2|3)\d{2}$/.test(status)) {
                        //成功的处理
                        switch (dataType.toUpperCase()) {
                            case 'JSON':
                                res = JSON.parse(response);
                                break;
                            case 'TEXT':
                                res = responseText;
                                break;
                            case 'XML':
                                res = responseXML;
                                break;
                        }
                        success && success(res, statusText, xhr);
                    } else {
                        //错误的处理
                        error && error(null, statusText, xhr)
                    }
                }

            }
            xhr.send(data);
        },
        //封装一个方法,专门用来处理对象转字符串的
        handleData: function () {
            //对data参数进行处理,规定当前函数的返回值就是处理完成之后的字符串
            let {
                data
            } = this.options;
            //let data=this.options.data;

            //如果当前的data是null或者是字符串,那就直接返回即可
            if (data === null || typeof data === 'string') {
                return data;
            }

            //只要上面的if没有成立,那就说明当前的data就是对象
            let str = ``;
            for (let key in data) {
                //为了防止把原型上的可枚举的属性遍历出来,利用hasOwnProperty处理一下
                if (!data.hasOwnProperty(key)) {
                    break;
                }
                str += `${key}=${data[key]}&`;
            }
            return str.slice(0, str.length - 1); //把最后的&截取下去
        },
        //根据url情况考虑拼接data时前面应该添加?还是&
        hasQuestionMark: function (url) {
            //此函数会直接返回?或者&
            //this-->实例
            if (!url) {
                url = this.options.url;
            }

            return url.includes('?') ? '&' : '?';
        },

    }
    //默认的参数配置
    let defaults = {
        url: '',
        method: 'GET', //默认是get请求,不区分大小写
        data: null,
        dataType: 'JSON',
        async: true,
        cache: true,
        timeout: null,
        headers: null, //{}//请求头中的值不能是汉字
        success: null, //请求成功之后的回调
        error: null,
    }

    function init(options) {
        //形参options就是用户传递的实参 this-->实例
        //1.把用户传递的options和默认的defaults进行合并,以用户传递的参数为主,如果用户没有传递某个参数,那就使用默认的

        // this.options=Object.assign(defaults,options)

        this.options = {
            ...defaults,
            ...options
        }; //把两个对象进行合并,如果出现相同的属性名,后边会覆盖前边的

        if (!this.options.url) {
            throw new Error('url is must be provided')
        }

        //2.发送ajax请求
        this.send();

    }
    init.prototype = ajax.prototype; //把ajax的原型赋值给init的原型

    if(typeof window !== "undefined"){
    	window.ajax = ajax; //把ajax方法暴露在window上
    }
})()

let res = ajax({
    url: './xxx.json',
    method: 'get',
    data: {
        name: 1,
        age: 2
    },
    cache: false,
    headers: {
        ss: 100,
        aa: '中国'
    },
    success: (data, statusText, xhr) => {
        console.log(data, statusText, xhr);
    },
    error: (data, statusText, xhr) => {
        console.log(data, statusText, xhr);
    }
}) //init的实例
console.log(res.xhr);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值