基于 xhr 实现 axios

基于 xhr 实现 axios

上面我们讲到二次封装 axios ,但是现在我们尝试完全脱离 axios,自己实现一个 axios,由于 axios 底层是基于 xhr 做了二次封装,所以我们也可以尝试一下。

xhr 二次封装

src/plugins/xhr.js

javascript 复制代码
/**
 * 请求拦截器队列
 * 响应拦截器队列
 */
const request = []
const response = []

/**
 * xhr 封装
 */
function axios(config) {
    return new Promise((resolve) => {
        request.forEach((fn) => (config = fn(config)))

        const { method, url, data, headers } = config

        /**
         * 新建请求
         */
        const xhr = new XMLHttpRequest()
        xhr.open(method, url)

        /**
         * 设置请求头
         */
        for (const key in headers) {
            xhr.setRequestHeader(key, headers[key])
        }

        /**
         * 发送请求
         */
        xhr.send(data)

        /**
         * 监听返回值
         */
        xhr.onreadystatechange = () => {
            if (!(xhr.readyState === 4 && xhr.status === 200)) return

            let data = JSON.parse(xhr.responseText)

            response.forEach((fn) => (data = fn(data)))

            resolve(data)
        }
    })
}

/**
 * 拦截器定义
 */
axios.interceptors = {
    request: {
        use: (fn) => {
            request.push(fn)
        }
    },
    response: {
        use: (fn) => {
            response.push(fn)
        }
    }
}

export default axios

axios 二次封装

src/plugins/axios.js

javascript 复制代码
import axios from './xhr'
import qs from 'qs'

/**
 * 请求拦截器
 */
axios.interceptors.request.use((config) => {
    config.data = qs.stringify(config.data)

    return config
})

/**
 * 响应拦截器
 */
axios.interceptors.response.use((response) => {
    if (response.code !== 200) {
        alert('接口响应失败')
    }

    return response
})

/**
 * 接口请求方法
 */
const request = (method, option) => {
    return axios({
        method: method,
        url: 'https://study.noxussj.top' + option.url,
        data: option.data,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    })
}

export default {
    get: (option) => request('get', option),
    post: (option) => request('post', option),
    put: (option) => request('put', option)
}

调用

javascript 复制代码
import axios from './plugins/axios.js'

/**
 * 发起请求
 */
const p1 = axios.post({
    url: '/api/login',
    data: { account: 'test', password: '123456' }
})

p1.then((res) => {
    console.log(res.data)
})

修改后预览效果,依然是可以正常请求接口。

原文链接:菜园前端

相关推荐
程序员码歌1 小时前
【零代码AI编程实战】AI灯塔导航-总结篇
android·前端·后端
七七&5561 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
元清加油2 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
用户21411832636022 小时前
免费玩转 AI 编程!Claude Code Router + Qwen3-Code 实战教程
前端
小小愿望3 小时前
前端无法获取响应头(如 Content-Disposition)的原因与解决方案
前端·后端
小小愿望3 小时前
项目启功需要添加SKIP_PREFLIGHT_CHECK=true该怎么办?
前端
烛阴3 小时前
精简之道:TypeScript 参数属性 (Parameter Properties) 详解
前端·javascript·typescript
向日葵.4 小时前
fastdds.ignore_local_endpoints 属性
服务器·网络·php
海上彼尚4 小时前
使用 npm-run-all2 简化你的 npm 脚本工作流
前端·npm·node.js
开发者小天4 小时前
为什么 /deep/ 现在不推荐使用?
前端·javascript·node.js