基于 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)
})

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

原文链接:菜园前端

相关推荐
Miracle&几秒前
2.TCP深度解析:握手、挥手、状态机、流量与拥塞控制
linux·网络·tcp/ip
秋秋小事6 分钟前
React Hooks useContext
前端·javascript·react.js
Jinuss8 分钟前
Vue3源码reactivity响应式篇之reactive响应式对象的track与trigger
前端·vue3
striver_#9 分钟前
百度前端社招面经二
前端
xcnn_10 分钟前
前端入门——案例一:登录界面设计(html+css+js)
前端·css·html
ST.J10 分钟前
前端笔记2025
前端·javascript·css·vue.js·笔记
拉不动的猪11 分钟前
回顾vue中的Props与Attrs
前端·javascript·面试
liulilittle28 分钟前
IP校验和算法:从网络协议到SIMD深度优化
网络·c++·网络协议·tcp/ip·算法·ip·通信
Jerry1 小时前
使用 Material 3 在 Compose 中设置主题
前端
耶啵奶膘1 小时前
uni-app头像叠加显示
开发语言·javascript·uni-app