第三十一章 ajax的简单封装

本文详细介绍了如何使用JavaScript封装一个AJAX函数,包括参数校验、默认值设定、数据转换以及错误处理。通过Promise实现异步操作,确保代码的可维护性和可读性。同时,展示了如何处理GET和POST请求,以及数据序列化和响应处理。
摘要由CSDN通过智能技术生成

一、用到小知识点

?? 空值运算 , 只要这个符号前面不为空 , 就是使用 , 如果前面为空了就使用后面的

二、封装

需要考虑以下几点

1、封装方案

若使用回调函数不利于我们代码的维护与阅读,我们可以利用Promise的形式进行封装

2、参数的默认值,不同的请求需要传递不同的参数

  •  请求地址(url):没有默认值

  • 请求方式(method),有默认值 , 默认发送 get

  • 是否异步(async):有默认值 , 默认值是 true

  • 传递参数(data):  有默认值 , 默认值就是 ''(空字符串)

  • 需要设置请求头信息(headers):有默认值 , 以对象的方式来传递 默认值:{ content-type :'application/x-www-form-urlencoded'}

  • 是否解析响应体(dataType):有默认值 , 默认值'string'

3、需不需要有返回值

按照 Promise 进行封装,需要一个返回值 , 这个返回值是 Promise 对象,将来我们使用的时候就可以在then或者是catch里面接收结果了

4、参数的设计(我们在封装的时候需要如何来安排我们的参数)

  • 参数的位置 , 和我们参数的数量

  • 我们将来在传递的时候需要好传递(方便我们传递)

  • 我们在封装的时候还要好接收这个参数

  • 我们参数的传递以对象的方式传递

  • 封装的时候 , 也是通过对象的方式来拿

function parseQueryString(obj) {
    var str = ''
    for (var k in obj) {
        str += k + '=' + obj[k] + '&'
    }
    str = str.slice(0, -1)
    return str
}

// let res = parseQueryString({ name: 'Rose', age: 20 })
// console.log(res);
// 查询字符串: key=value&key1=value1&key2=value2
// 这里是我们的封装的过程

function ajax(options = {}) { 
    // console.log(options);
    // 首先需要拿到传递进来的参数
    const { url, method, async, data, headers, dataType} = options;
    // 就是需要对我们传递进来的参数进行验证了
    // 1. 验证我们的每一个参数
    // 验证 url
    if (!url || typeof url !== 'string') throw new Error('url必须传递 而且是一个字符串,格式不对')
    // 验证 method
    if (!(method === undefined || /^(get|post)$/i.test(method))) throw new Error('你传递到的请求方式不正确 , 核对后再试')
    // 验证 async
    if (!(async === undefined || typeof async === 'boolean')) throw new Error('这里需要的是一个布尔数据类型, 你传递的不正确')
    // 验证 data
    // 这里也可以传递一个对象 , 我在这里给你转成查询字符串
    if (!(data === undefined || typeof data === 'string' || Object.prototype.toString.call(data) === '[object Object]')) { 
        throw new Error('这里必须是一个字符串数据类型或者是对象数据类型 , 你传递的不正确')
    }
    // 验证headers
    if (!(headers === undefined || Object.prototype.toString.call(headers) === '[object Object]')) { 
        throw new Error('这里我们需要的是一个对象数据类型 , 你传递的不正确')
    }
    // 验证 dataType
    if (!(dataType === undefined || /^(string|json)$/i.test(dataType))) throw new Error('dataType只能是一个string或者是json')


    // 2. 设置一套默认值
    const _default = {
        // url 没有默认值 , 你传递什么我使用什么
        url: url,
        // method 如果你传递了使用你传递的 , 没有传递的时候我们使用的是默认值
        method: method || 'GET',
        // async 如果你传递了使用你传递的 , 没有传递的时候我们使用的是默认值
        async : typeof async === 'boolean' ? async : true,
        // async : async ?? true // ?? 空值运算 , 只要这个符号前面不为空 , 就是使用 , 如果前面为空了就使用后面的
        // data 如果你传递了使用你传递的 , 没有传递的时候我们使用的是默认值
        data: data || '',
        // headers 如果你传递了使用你传递的 , 没有传递的时候我们使用的是默认值
        headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },
        // dataType 如果你传递了使用你传递的 , 没有传递的时候我们使用的是默认值
        dataType: dataType || 'string'
    }

    // 2-1 默认值的操作
    // 如果你携带的参数是以对象的方式携带的
    // 就需要把对象转成查询字符串
    // 首先要确定你传递进来的一定是一个对象
    if (typeof _default.data === 'object') { 
        // 代码能执行到这里 , 说明一定是一个对象
        // 需要把对象转成查询字符串
        _default.data = parseQueryString(data)
    }
    // 2-2 . 如果你是get请求 , 并且携带了参数 , 这个时候我们就可以给你拼接好了
    if (/^get$/i.test(_default.method) && _default.data) { 
        // 代码能执行到这里 , 说明是get请求 并且携带了参数
        _default.url = _default.url + '?' +_default.data
    }

    // 3. 发送请求
    // 我们一开始就决定了要使用Promise的形式进行封装
    const p = new Promise(function (resolve, reject) { 
        // 创建ajax对象
        const xhr = new XMLHttpRequest()
        // 配置请求信息
        xhr.open(_default.method, _default.url, _default.async)
        // 注册一个响应函数
        xhr.onload = function () { 
            // let res = xhr.responseText
            //如果是 string 直接把这个结果给你返回就好了
            // 如果是 json 我们就需要帮你解析完了以后再给你
            if (_default.dataType === 'string') {
                // 代码能执行到这里 , 说明后端返回的是就是一个普通字符串
                // resolve(xhr.responseText)
                resolve({code:1, message:'成功',info:xhr.responseText})
            } else { 
                // 后端返回的是不是一个普通字符串 , 就是JSON格式字符串
                // 需要我们做的是容错处理
                try { 
                    let res = JSON.parse(xhr.responseText)
                    resolve({code:1, message:'成功',info: res})
                } catch (err) { 
                    resolve({code:0, message:'失败',info: err})
                }
            }
        }
        // 如果是post请求 , 还要设置一个请求头
        // 因为是一个对象 ,我们要从对象中拿到我们需要的内容
        // 循环遍历我们的对象了
        for (let k in _default.headers) { 
            xhr.setRequestHeader(k,_default.headers[k])
        }
        // 如果是get请求 , 可以直接发送
        // 如果是post请求 ,有参数 我们需要在请求体中携带参数
        if (/^get$/i.test(_default.method)) {
            xhr.send()
        } else { 
            xhr.send(_default.data)
        }
    })
    // 最后我们是不是要返回这个Promise对象
    return p
}




// 将来使用
// let res = ajax({
//     url: 'http://localhost:8888/test/fourth',
//     method: 'post',
//     // async: false,
//     // 可以以对象的方式进行传递
//     // data: 'name=Rose&age=30',
//     data: {
//         name: 'Tom',
//         age:50
//     },
//     // headers: {},
//     dataType: 'json',
// })
// res.then(r => console.log(r.info.info))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值