封装Ajax ( 简单模仿axios )

265 阅读1分钟
原生Ajax + Promise , 封装 GET/POST/PUT/DELETE 请求
json-server 模拟接口
  • ajax封装如下:
function axios({
    url,
    method = "GET",
    data = {},
    params = {}
}) {
    return new Promise((resolve, reject) => {
        // 处理method大小写
        method = method.toUpperCase()
        // 处理url和参数 (简单处理 , 需要前提是url原本是不带参数后缀的)
        // queryString 是作为params拼接后的字符串
        let queryString = '';
        Object.keys(params).forEach(key => {
            //  key=params[key]& 
            queryString += `${key}=${params[key]}&`
        })
        // 除掉queryString的最后一个 &  , substring 截取返回的是个新字符串 , 不影响原来字符串
        queryString = queryString.substring(0, queryString.length - 1)
        // 拼接url 
        url += '?' + queryString;

        // 发起Ajax请求
        let xhr = new XMLHttpRequest();
        // 启动一个请求以备发送
        xhr.open(method, url)
        // 发送请求
        // 先判断请求方式
        if (method === "GET" || method === "DELETE") {
            // get 请求的 send 里面不用加上data
            xhr.send()
        } else if (method === "POST" || method === "PUT") {
            // 加上data之前 先设定请求体data的格式
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.send(data) // data 数据格式为  data: 'name=王珞丹'  , 不用转化 data 数据格式 , 原本就是字符串

            //  xhr.setRequestHeader("Content-Type","application/json;charset=utf-8") 
            //  对应的 data 请求体数据格式 是对象 data :{"name":"王珞丹"} 
            //  xhr.send(JSON.stringify(data))   这里就需要把对象格式转换为 字符串 
        }

        // 监听请求状态的改变
        xhr.onreadystatechange = function () {
            // 如果请求失败 直接停止
            if (xhr.readyState !== 4) {
                return false
            }
            // 解构出 请求的 status statusText
            const {
                status,
                statusText
            } = xhr;
            if (status >= 200 && status < 300) {
                // 模拟axios , 设置响应体 response的数据对象 
                const response = {
                    status,
                    statusText,
                    // responseText 需要转换成json对象格式
                    data: JSON.parse(xhr.responseText)
                }
                // 请求成功 执行resolve回调 
                resolve(response)
            } else {
                reject(new Error(`request failed , the status is ` + status))
            }
        }
    })
}
  • json-server 的 db.json
{
  "girls": [
    {
      "name": "石原里美",
      "id": 1
    },
    {
      "name": "全智贤",
      "id": 3
    },
    {
      "id": 4,
      "name": "程潇"
    }
  ],
  "players": [
    {
      "name": "利拉德",
      "id": 1
    },
    {
      "name": "保罗",
      "id": 2
    },
    {
      "name": "詹姆斯",
      "id": 3
    },
    {
      "name": "杜兰特",
      "id": 4
    },
    {
      "name": "塔克",
      "id": 5
    }
  ]
}
  • 触发请求的部分代码
 // get
        function handleGet() {
            axios({
                url: 'http://localhost:3000/girls',
                method: 'GET',
                parmas:{
                  id : 3
                }
            }).then(
                response => {
                    console.log(response.data)
                },
                err => {
                    console.log(err.message)
                }
            )
        }
        // post
        function handlePost() {
            axios({
                url: "http://localhost:3000/girls",
                method: 'post',
                data:'name=程潇'           // 对应的是 post put请求时候 请求头里设置的数据格式为   xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            }).then(response => {
                console.log(response.data)
            }).catch(err => {
                alert(err.message)
            })
        }
        // del
        function handleDel() {
            axios({
                url: "http://localhost:3000/girls/4",
                method: 'delete'
            }).then(response => {
                console.log(response.data)
            }).catch(err => {
                alert(err.message)
            })
        }
        // put
        function handlePut() {
            axios({
                url: "http://localhost:3000/girls/1",
                method: 'PUT',
                data: 'name=石原里美'         // 对应的是 post put请求时候 请求头里设置的数据格式为  xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            }).then(response => {
                console.log(response.data)
            }).catch(err => {
                alert(err.message)
            })
        }