手写Axios

84 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

API介绍

语法:

  • axios(options)
    • 参数配置对象:url、method、params、data
    • 返回值为:promise对象
  • axios.get(url,options)
  • axios.post(url,data,options)
  • axios.put(url,data,options)
  • axios.delete(url,options)

功能:使用xhr发送ajax请求的工具函数,与axios库功能类似

// 使用方式一: 函数方式使用
axios({
	// 请求的类型
	method:'POST',
	// 请求的url
	url:'http://127.0.0.1',
	// url参数
	params:{
	  a:1,
	  b:2
	},
	// 请求体
	data:{
	  c:3,
	  d:4
	}
}).then(res=>{
    console.log(res)
})

// 使用方式二: 调用对象方法
axios.get('http://127.0.0.1',{
	params:{
		a:1,
		b:2
	}
}).then(res=>{
	console.log(res)
})

axios.post('http://127.0.0.1',{
	params:{
		a:1,
		b:2
	}
}).then(res=>{
	console.log(res)
})

实现:

  • 结构:方法接收一个对象参数,对象内包括:method,url,params,data

    这样传参数的好处:这样就可以在函数当中直接使用变量,来使用对象当中的属性。

  • 功能实现:

    • 方法转换为大写

    • 返回值。返回值是一个promise对象,使用直接new一个promise返回。然后在promise中进行ajax操作。

      Asynchronous JavaScript And XML(异步 JavaScript 及 XML)

      Ajax的作用:实现异步请求的技术。

      Ajax的使用:1.创建Ajax对象 2.链接到服务器 3.发送请求 4.接受返回值

      1. 创建Ajax对象

      2. 链接到服务器。这里发起请求前需要先处理一下params对象 变成 这样的 a=1&b=2 才能发送。

        通过for in 遍历,键值对之间用&分隔,最后通过slice(0,-1)截取最后一个&

        在open参数内传入url需要追加?+str,拼接上

      3. 发送请求。判断是否为 POST、PUT、DELETE

        这里要注意一下请求体。get方法请求体一般为空,post、put请求体有内容。

        注意:

        ​ 请求体是对象,我们需要把请求体转化为字符串。

        ​ 需要为它们设置请求头 Comtent-type 目的是为了告诉浏览器发送的是什么样格式的数据。

        • 如果是以上三种方法,
          • 设置请求头 Comtent-type mime 类型设置。设置请求头,并告诉浏览器要发送的格式为 'application/json'
          • 则需要设置请求体。将请求体data转为字符串,并send(data)
        • 如果不是以上三种方法,直接send()

        接受返回值前,需要设置响应结果的类型为 JSON

        xhr.responseType = 'json'

      4. 接受返回值

        • 判断readyState是否等于4。

        Ajax.readyState浏览器和服务器的交互情况

        • 判断响应状态码是否等于200。http状态码,用来判断是否成功接受并返回文件

          • 是,说明成功,设置成功状态。

            通过resolve设置成功状态,并在参数中返回的对象为:

            {status:xhr.status,message:xhr.statusText,body:xhr.response}

          • 不是,说明失败。设置失败状态。

            通过reject设置失败状态,并new一个Error方法的对象当参数传入。

            reject(new Error('请求失败,失败状态码为:'+xhr.status))

  • 实现第二种方式:调用对象方法

    • 结构:方法接收两个参数,第一个是url,第二个是对象
    • 利用拷贝,将传入的对象拷贝到options中
    • 将拷贝的结果将参数传递给已经封装好的axios

代码

index.js

function axios({
  method,
  url,
  params,
  data
}) {
  // 返回值。返回的是一个promise对象
  return new Promise((resolve, reject) => {
    // 方法转换为大写
    method = method.toUpperCase()
    // 1.创建Ajax请求
    const xhr = new XMLHttpRequest();
    // 2.连接到服务器。先处理params请求
    let str = ''
    for (let k in params) {
      str += `${k}=${params[k]}&`
    }
    str = str.slice(0, -1)
    // url拼接str
    xhr.open(method, url + '?' + str)
    console.log(url)
    // 3.发送请求
    if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
      // 设置请求头 Comtent-type
      xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8')
      // 设置请求体
      xhr.send(JSON.stringify(data))
    } else {
      xhr.send()
    }
    // 4.接收返回值
    xhr.onreadystatechange = function () {
      // 判断readyState
      if (xhr.readyState === 4) {
        // 判断响应状态码是否等于200
        if (xhr.status === 200) {
          // 成功状态
          resolve({
            status: xhr.status,
            messaget: xhr.statusText,
            body: xhr.response
          })
        } else {
          // 失败状态
          reject(new Error('请求失败,失败状态码为:' + xhr.status))
        }
      }
    }
  })
}

测试.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./index.js"></script>
</head>

<body>
  <script>
    // 使用方式一: 函数方式使用
    axios({
      // 请求的类型
      method: 'POST',
      // 请求的url
      url: 'http://175.178.xxx.236:8889/users/login',
      // url参数
      params: {
        a: 1,
        b: 2
      },
      // 请求体
      data: {
        username: 'admin',
        password: 123456,
        type: 1
      }
    }).then(res => {
      console.log(res)
    })

    /*   // 使用方式二: 调用对象方法
      axios.get('http://127.0.0.1', {
        params: {
          a: 1,
          b: 2
        }
      }).then(res => {
        console.log(res)
      })

      axios.post('http://127.0.0.1', {
        params: {
          a: 1,
          b: 2
        }
      }).then(res => {
        console.log(res)
      }) */
  </script>
</body>

</html>