使用原生js封装自己的ajax函数

191 阅读3分钟

平时都是用axios封装的ajax函数去发起ajax请求,那我们是否可以使用原生js去封装并发起ajax请求呢?答案是完全可以的。要封装属于自己的ajax函数,首先要知道axios的原理是基于new出来的XMLHttpRequest实例对象来发起ajax请求的,而XMLHttpRequest是浏览器内置的一个构造函数。那么意味着我们便可以直接通过js来使用这个构造函数。在使用XMLHttpRequest发起请求的时候要使用.open().setRequestHeader().send()函数去分别传递请求的行头体。

一、请求体格式和对应的Content-Type值

为了方便服务器接收数据,当提交请求体时,需要指定一个叫做Content-Type的请求头,使用axios不用关心请求头,因为axios帮我们处理好了加请求。但是想用原生js代码封装自己的ajax函数就需要自己指定,所以要了解下面3种不同的请求体格式和与之对应的Content-Type。

请求体格式Content-Type是否需要在代码中指定
参数=值&参数=值application/x-www-form-urlencoded
'{ "id": 1, "name": "zs" }'application/json
new FormData()multipart/form-data; xxxxxxxxx随机字符否,浏览器自动设置

二、封装ajax函数主要分为下面几个步骤:

  1. 定义myAjax这个自定义函数,接受method, url, params, data, success这几个主要参数。
  2. 创建XMLHttpRequest的实例对象xhr
  3. 单独为get添加判断条件,为唯一不一样的params拼接url
  4. 调用xhr.open()函数发送请求method和url路径
  5. 处理其他data请求体数据,根据不同的请求体数据,设置对应的请求头的Content-Type类型。
  6. 调用xhr.setRequestHeader()函数:(GET请求比较特殊,它不用请求头)
  7. 调用xhr.send()函数:(GET请求调用send不用传递数据或直接用send传递null)

三、实现

//由于params的到的值是对象,所以要把它变成字符串用&拼接一起,方便后续放
//进url传递到服务器端
function parseObjectToString(obj) {
    let arr = []
    for (let key in obj) {
        arr.push(key + '=' + obj[key])
    }
    return arr.join('&')
​
}
​
//接收method, url, params, data, success这几个主要参数
function myaxios({ method, url, params, data, success }) {
  //创建XMLHttpRequest对象
  let xhr = new XMLHttpRequest()
    //判断是否为get请求和是否有传递params数据
    if (method.toLowerCase() == 'get' && params) {
      //拼接参数到url的末端
        url += '?' + parseObjectToString(params)
    }
    //发送对应的method和url请求
    xhr.open(method, url)
​
  //判断data的数据类型,分别调用不同的请求头类型
    if (data instanceof FormData) {
      //如果是FormData对象就直接传递data发送请求,不需要指定请求头类型
        xhr.send(data)
    } else if (typeof data == 'object') {
      //如果data是对象,就要指定Content-Type为
      //application/json的请求头类型
        xhr.setRequestHeader('Content-Type', 'application/json')
      //把对象转换成JSON字符串发送
        xhr.send(JSON.stringify(data))
    } else if (typeof data == 'string') {
      //如果data是字符串,就要指定Content-Type为
      //application/x-www-form-urlencoded的请求头类型
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      //直接发送字符串
        xhr.send(data)
    } else {
      //单独为get请求发送无参的send()
        xhr.send()
    }
  
  //使用回调函数获取服务器端响应信息
    xhr.addEventListener('load', function () {
        success(JSON.parse(xhr.response))
    })
}