实现简易的 axios

1、实现逻辑

Promise + XMLHttpRequest 封装

① 返回一个 promise 实例

new XMLHttpRequest 并设置默认请求方式、请求根路径;

添加请求+响应事件;

根据状态码,对应执行成功或者失败的调用函数,并把结果传进去;

② 处理 params

如果有 params,就 new URLSearchParams() 对象,并把传进来的 params 传到对象里;

再用 toString 方法转成 URL 编码字符串,最后再拼接 url 来覆盖 url 默认值

③ 处理 data

如果有 data,就 xhr.setRequestHeader 设置请求头的请求数据类型;

比如 JSON 字符串,就还需要用 JSON.stringify 转成 JSON 字符串

最后传到 send 携带 JSON 字符串发起请求

2、封装代码

javascript 复制代码
  // 实现简易的axios   
  function myAxios(config) {
    return new Promise((resolve, reject) => {
      // 实例化xhr
      const xhr = new XMLHttpRequest()
      // 默认get请求
      let { methods = "get", url, params = "", headers = "", data = "" } = config
      // 将传入的params对象转成URL编码字符串
      if (params) {
        const parseParams = new URLSearchParams(params)
        url += `?${parseParams.toString()}`
      }
      // 设置请求方法+请求地址
      xhr.open(methods, url)
      // 设置请求头
      if (headers) {
        Object.keys(headers).forEach((key) => {
          xhr.setRequestHeader(key, headers[key])
        })
      } else {
        xhr.setRequestHeader("Content-Type", "application/json")
      }
      // 添加请求响应事件
      xhr.addEventListener("loadend", () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          // 成功
          resolve(JSON.parse(xhr.response))
        } else {
          reject(new Error(xhr.response))
        }
      })
      // data对象
      if (data) {
        // 设置请求头,请求数据类型设置为 JSON 字符串
        xhr.setRequestHeader("Content-Type", "application/json") // 转 JSON 字符串
        // 构造参数
        const jsonDate = JSON.stringify(data)
        // 发起请求
        xhr.send(jsonDate)
      } else {
        // 发起请求
        xhr.send()
      }
    })
  }

3、使用

javascript 复制代码
  // 使用
  myAxios({
    methods: "get",
    url: "/1.json",
    headers: {
        "token": "123"
    },
    params: {
      name: "strawberry",
      age: 18,
    },
    // data: {
    //   name: "strawberry",
    //   age: 18,
    // },
  })
    .then((res) => {
      console.log("成功", res);
    })
    .catch((err) => {
      console.log("失败", err);
    });
相关推荐
Csvn2 小时前
`??` 和 `||` 搞混,线上用户头像全挂了
前端
kyriewen2 小时前
白宫前脚下了限制令,OpenAI 后脚就把 GPT-5.6 发了
前端·gpt·openai
用户40269244819083 小时前
CRMEB Pro 新增后台接口全链路:路由、权限、验证器、返回格式一次讲清
前端·后端
泉城老铁3 小时前
springboot+vue+ ffmpeg 实现视频的拉流播放
前端
PedroQue994 小时前
uni-router v1.8.0新增冷启动守卫补执行
前端·uni-app
xiaok4 小时前
部署之后,本地浏览器还在读取旧缓存导致页面一直显示loading中
前端
用户059540174464 小时前
Redis缓存一致性踩坑实录:线上故障排查6小时,我用pytest+内存快照把它永久关进了笼子
前端·css
星栈4 小时前
我用 Rust + Dioxus 做了个全栈跨平台笔记应用:第一版先把列表和详情跑通
前端·rust·前端框架
用户1733598075374 小时前
Vue 3 SPA 首屏优化:从 3s 到 1.2s 的 5 个实践
前端·vue.js
咖啡无伴侣4 小时前
基础骨架:30 分钟搭好 pnpm workspace,完成双项目 Monorepo 迁入
前端