自己练习封装的基于promise的ajax

本文介绍了一种基于Promise设计模式的AJAX封装方法,通过自定义ajaxPromise.js,实现了GET、POST等请求方式,支持参数处理、请求头设置及响应结果解析,展示了如何在项目中应用此封装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己练习封装的基于promise的ajax

// ajaxPromise.js

    ~ function (window) {
        //=> 设置默认的参数配置项
        let _default = {
            method: 'get',
            url: '',
            baseURL: '',
            headers: {},
            dataType: 'JSON',
            data: null, //=> post系列请求基于请求主体传递给服务器的内容
            params: null, //=> get系列请求给予问号传参传递给服务器的内容
            cache: true,
        };
        //=> 基于Promise设计模式管理AJAX请求
        let ajaxPromise = function ajaxPromise(options) {
            //=> options 中融合了:默认配置信息,用户基于defaults修改的信息,用户执行get/post方法时候传递的配置信息,越靠后的优先级越高
            let {
                url,
                baseURL,
                method,
                data,
                dataType,
                headers,
                cache,
                params,
            } = options;

            //=> 把传递的参数进一步处理
            if (/^(get|delete|head|options)$/i.test(method)) {
                //=> get 系列
                if (params) {
                    url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
                }
                //= > 是否需要缓存
                if (cache === false) {
                    url += `${ajaxPromise.check(url)}_=${+(new Date())}`;
                }
                data = null; //=> get系列请求主体就是什么都不放
            } else {
                //=> post 系列
                if (data) {
                    data = ajaxPromise.formatData(data);
                }
            }
            //=> 把对象转换为urlencoded格式的字符串
            ajaxPromise.formatData = function (obj) {
                let str = ``;
                for (let key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        str += `${key}=${obj[key]}&`;
                    }
                }
                return str.substring(0, str.length - 1);
            };
            //=> 检测url是否有?传参
            ajaxPromise.check = function (str) {
                return str.includes('?') === true ? '&' : '?';
            }
            //=> 基于Promise发送AJAX
            return new Promise((resolve, reject) => {
                let xhr = new XMLHttpRequest;
                xhr.open(method, `${baseURL}${url}`);
                //=> headers存在,我们需要设置请求头
                if (headers !== null && typeof headers === 'object') {
                    for (let attr in headers) {
                        if (headers.hasOwnProperty(attr)) {
                            let val = headers[attr];
                            //=> 检测中文
                            if (/[\u4e00-\u9fa5]/.test(val)) {
                                //=> val中包含中文:我们把它进行编码
                                // encodeURLComponent / decodeURLComponent  
                                val = encodeURIComponent(val);
                            }
                            xhr.setRequestHeader(attr, val);
                        }
                    }
                }
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4) {
                        if (/^(2|3)\d{2}$/.test(xhr.status)) {
                            let result = xhr.responseText;
                            dataType = dataType.toUpperCase();
                            //=> 判断dataType类型
                            switch (dataType) {
                                case 'JSON':
                                    result = JSON.parse(result);
                                    break;
                                case 'XML':
                                    result = xhr.responseXML;
                                    break;
                            }

                            resolve(result);
                            window.ajaxPromise.nowXHR = xhr;
                            return;
                        }
                        reject(xhr.statusText);
                        window.ajaxPromise.nowXHR = xhr;
                    }
                }
                xhr.send(data);
            })

        };
        //=> defaults暴露出去,以后别人可以修改
        //=> 把默认配置暴露出去,后期用户在使用的时候可以自己设置一些基础的默认值(发送ajax请求的时候按照配置的信息进行处理)
        ajaxPromise.defaults = _default;


        //=> get
        ['get', 'delete', 'head', 'options'].forEach(item => {
            ajaxPromise[item] = function (url, options = {}) {
                options = {
                    ..._default, //=> 默认值或者基于defaults修改的值
                    ...options, //=> 用户调取方法传递的配置项
                    url: url, //=> 请求的url地址 (第一个参数:默认配置项和传递的配置项中都捕获出现url,只能这样做)
                    method: item.toLowerCase() //=> 以后执行肯定是ajaxPromise.head执行,不会设置methods这个配置项,我们自己需要配置才可以
                };
                return ajaxPromise(options);
            }
        });

        //=> post
        ['post', 'put', 'patch'].forEach(item => {
            ajaxPromise[item] = function (url, data = {}, options = {}) {
                options = {
                    ..._default,
                    ...options,
                    url: url,
                    method: item.toLowerCase(),
                    data: data
                };
                return ajaxPromise(options);
            }
        })
        //=> 暴露出去
        window.ajaxPromise = ajaxPromise;
    }(window)

用法

<script src="ajaxPromise.js"></script>
<script>
    //=> 默认设置
    //=> 设置默认请求路径 
    ajaxPromise.defaults.baseURL = 'https://www.easy-mock.com/mock/5b0412beda8a195fb0978627/temp';

    ajaxPromise.get('/list').then(result=>{
        console.log(result);
    })

    ajaxPromise.get('/info',{
        params: {
            id:1000
        },
        cache:false
    }).then(result=>{
        console.log(result);
    })

    ajaxPromise.post('/add',{
        name:'jun',
        age:16
    },{
        headers:{
            'content-type':'x-www-form-urlencoded'
        }
    }).then(result =>{
        console.log(result);
    })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值