手写 axios

243 阅读1分钟

手写 axios

// 手写简单的axios
/* 
1.函数返回值为promise对象,成功结果为xhr.response,失败的结果为error
2.能处理多种类型的请求,get/post/put/delete
3.函数的参数为一个配置对象
{
    url:"",//请求地址
    method:"",//请求方式
    params:{},//请query参数
    data:{},//请求体参数
}
4.响应json数据自动解析为js的对象/数组
*/
function axios(config) {
    let {
        url,
        method = 'GET',
        params = {},//指定query参数
        data = {} //指定请求体参数,默认请求体参数的编码形式为json
    } = config
    return new Promise((resolve, reject) => {
        method = method.toUpperCase() //用户有可能会乱传参数,如PosT,此时需要统一转大写
        //query参数 把{a:1,b:2}转成a=1&b=2
        let queryStr = "" //用于存储query参数
        for (let key in params) {
            queryStr += `${key}=${params[key]}&`
        }
        if (queryStr) queryStr = queryStr.substring(0, queryStr.length - 1) //判断是否有参数
        // 请求体参数
        data = JSON.stringify(data)
        // 实例化xhr对象
        const xhr = new XMLHttpRequest()
        // 绑定监听
        xhr.onreadystatechange = () => {
            if (xhr.readyState !== 4) return
            if (xhr.status >= 200 && xhr.status <= 299) {
                const { status, statusText, response } = xhr
                resolve({
                    status,
                    statusText,
                    data: JSON.parse(response)
                })
            } else {
                reject(new Error('请求失败'))
            }
        }
        // 判断请求方式
        if (method == 'GET') {
            xhr.open(method, url + "?" + queryStr)
            xhr.send()
        } else {
            xhr.open(method, url)
            xhr.setRequestHeader("Content-Type", "application/json")
            xhr.send(data)
        }
    })
}
export default axios