ajax封装思路

100 阅读3分钟

​ 一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

周日, 我被玛莎拉蒂小姐姐请吃饭了,为什么我会被请吃饭呢,竟然是因为一个ajax封装。

对,你们没有看错,就是对ajax的封装, 因为玛莎拉蒂小姐姐所在的公司使用原生ajax发送请求,而她恰巧不会,于是我就这单身许久的小伙就.........,后面嘛兄弟们懂得都懂。

接下来我们从技术角度出发来看我教玛莎拉蒂小姐姐写的代码

function request(url, type, objCallback, data, isAsync = true) {
        // 兼容低版本参数默认值写法
        isAsync === undefined ? isAsync = true : isAsync;
        let xhr;
        // 如果当前浏览器支持xmlhttpRequest则创建xmlhttpRequest否则创建ActiveXObject
        window.XMLHttpRequest ? xhr = new XMLHttpRequest() : xhr = new ActiveXObject("Microsoft.XMLHTTP");
        //2、建立一个连接
        xhr.open(type,url, isAsync);
        // 如果请求方法为post类型
        if(type === "post") {
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            if(data) {
                // 如果data存在而且类型为对象
                if(Object.prototype.toString.call(data) === "[object Object]") {
                    // 创建一个strData变量用来翻译对象格式传参
                    let strData = "";
                    // 循环遍历传进来的data参数
                    for(let key in data) {
                        // 将每个参数拼接进strData中
                        strData += `&${key}=${data[key]}`        
                    }
                    // 将strData的值从第一个字符截取到最后一个字符并重新赋值给参数data
                    data = strData.slice(1);
                }else{
                    return console.error("请使用对象形式传参,示例:\n{id: '1', name: '小语'}")
                }
            }
            xhr.send(data)
        }else {
            xhr.send(null)
        }
        //4、处理响应的结果    
        xhr.onreadystatechange = ()=>{
            if(xhr.readyState==4) {
                // 如果成功拿到返回结果则执行成功的回调
                if(xhr.status==200){
                    objCallback.success(JSON.parse(xhr.response))
                }
                // 如果没有拿到成功的返回结果则执行失败回调
                else {
                    objCallback.fail(xhr.status);
                }
            }
        }
    }

想要弄明白这个ajax的封装函数,我们先要来思考一个问题,我们封装的函数都需要哪些参数呢

  1. 请求地址

  2. 请求类型

  3. 请求完成后的处理函数

  4. 请求参数

  5. 同步请求或异步请求

这就是我们所需要完成一个较简单的封装函数的基本所需参数

有了这些参数后,我们就可以进行进一步的判断了,我们先来了解一下最常见的两种请求:

get:

        1.没有请求头

        2. 参数可以直接拼接在请求地址后

post: 

        1. 有请求头

        2. 参数必须传在send()方法中

因为不同的特点我们需要对请求类型参数 type 进行一个判断:

 // 如果请求方法为post类型
        if(type === "post") {
            // 携带请求头
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            // 传入响应参数
            xhr.send(data)
        }else {
            xhr.send(null)
        }

这样我们就完成了一个简单的对请求类型的判断

当请求地址和请求类型和携带参数的问题都解决了以后我们应该考虑的就是当拿到返回的数据后如何在正确的地方进行操作:

由于这里会有接口成功返回数据和接口请求失败的提示,所以我们可以在这里就会用到回调参数,但如果仅有一个回调那么无法确定是请求数据成功还是失败,所以我在这里更推荐大家使用对象方法的方式作为回调函数

//处理响应的结果    
xhr.onreadystatechange = ()=>{
    if(xhr.readyState==4) {
       // 如果成功拿到返回结果则执行成功的回调
       if(xhr.status==200){
            objCallback.success(JSON.parse(xhr.response))
       }
       // 如果没有拿到成功的返回结果则执行失败回调返回错误码
       else {
            objCallback.fail(xhr.status);
       }
    }
}

就像这样你就可以找到参数中的对象中的scueess方法和fail方式一个是成功一个是失败

这样你就完美解决了异步带来的影响。

接下来就是调用示例啦,在这里我为大家提供了两个可以直接获取数据的接口,不会出现跨域问题,在这里声明一下,接口是我写的,大家不必担心,这是面向大家尤其是新手的一个测试接口。

get示例:


    request("http://101.34.126.228:7777/v1/hoses/selectXiaoquInfo?cid=1","get",{
        success:(res)=>{
           let kuang = document.querySelector(".kuang");
           let str = ""
           res.info.forEach((e,index) => {
               str+= `<div class="kuang-item">
                    <h3 class="title">${e.title}</h3>
                    <p class="content">${e.content}</p>
                </div>`
           });
           kuang.innerHTML = str;
        },
        fail: (err)=> {
            console.log(err);
        }
    })

post示例:


    request("http://101.34.126.228:7777/v1/users/login","post",{
        success:(res)=>{
           let kuang = document.querySelector(".kuang");
           let str = ""
           res.info.forEach((e,index) => {
               str+= `<div class="kuang-item">
                    <h3 class="title">${e.title}</h3>
                    <p class="content">${e.content}</p>
                </div>`
           });
           kuang.innerHTML = str;
        },
        fail: (err)=> {
            console.log(err);
        }
    }, {
        uiphone: 18888888888,
        upassword: 123456789
    })

  来看一下参数

function request(url, type, objCallback, data, isAsync = true)

第一个为请求地址,第二个为类型

第三个为对象回调:这个参数应为对象且对象中有两个方法分别是success和fail可以只写success,这个方法上有一个参数就是成功的响应结果

第四个参数为请求post接口时要携带的参数

第五个参数为是否为异步请求, 默认情况下就是异步,大家根据需求使用。

最后非常感谢大家能阅读到这里,这也就是我封装时的一个大致思路,很多东西都还存在脑子中,未来会随着文笔越来越好,尽量向让大家完全读懂。

天才无非是长久的忍耐,努力吧!