axios

Axios

1.基础准备:

请求报文:
请求行(method,url),
请求头(比如Host:www.baidu.com,Cookie:xxx,Content-Type:application/x-www-form-urlencoded 或 application/json或 multipart/form-data:文件上传格式),
请求体(格式一:username=tom&age=18;格式二:{“username”:"tom})

响应报文:
响应状态行 (state:200 状态码对应的文本)
多个响应头 (Content-Type:响应体类型 Set-Cookie)
响应体 (图片、等)

请求方式:(9种)
常用 get:请求数据 post:添加数据 put:更新数据 delete:删除数据

携带参数 query:?id=1 过滤数组得到对象 和 param:/1 直接得到对象

2.ajax

什么是ajax?

ajax请求是一个特殊的http请求,对服务器端来说没区别,区别在于浏览器端
浏览器端:xhr或fetch发送的才是ajax请求

ajax与一般请求区别

一般请求:浏览器一般会直接显示响应体,也就是我们平常说的刷新、跳转页面
ajax请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入响应的相关数据

ps:可以查查 XHR api

3.axios

1.介绍

axios的特点:

  • 有请求/响应拦截器:axios.interceptors.request/response.use()
  • 数据转换
  • 返回的是promise对象
  • 批量执行多个异步请求 axios.all(promise)
  • 可以取消请求

axios语法:略

开发中通常会对axios二次封装

2.手动封装ajax请求,实现最简单的axios
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script>
    function axios({
                       url,
                       method = 'GET',
                       params = {},
                       data = {}
                   }) {
        //返回一个promise对象
        return new Promise((resolve, reject) => {
            method = method.toUpperCase();
            //处理query参数(拼接到url上) id=1&name=abc
            let queryString = ''
            Object.keys(params).forEach(key => {
                queryString += `${key}=${params[key]}&`
            })
            if (queryString) {
                //去除最后多的&
                queryString = queryString.substring(0, queryString.length - 1)
                url += '?' + queryString
            }
            //执行异步ajax请求
            let request = new XMLHttpRequest()
            //初始化,建立连接,true是异步,false是同步
            request.open(method, url, true)
            //发送请求
            if (method === 'GET' || method === 'DELETE') {
                request.send()
            } else if (method === 'POST' || method === 'PUT') {
                //告诉服务器请求体的格式为json
                request.setRequestHeader('Content-Type', 'application/json;charset=utf-8')
                request.send(JSON.stringify(data))
            }

            //绑定状态改变的监听
            //因为send()是异步的,所以监听写在这也行,肯定是先绑定监听再发请求
            request.onreadystatechange = function () {
                if (request.readyState !== 4) {
                    return
                }
                //如果响应状态码在[200,300)之间表示成功,否则失败
                const {status, statusText} = request
                // 成功
                if (status >= 200 && status < 300) {
                    //准备结果对象
                    const response = {
                        data: JSON.stringify(request.response),
                        status,
                        statusText
                    }
                    resolve(response)
                } else {
                    // 失败
                    reject(new Error('request error,错误码' + status + statusText))
                }
            }
        })
    }

    axios({
        url: '/xxx',

    })
</script>
</body>
</html>
3.注意点

axios和axios.creat()出来的instance是一个函数并非实例对象,这样可以给不同端口发请求

const instance = axios.create({
    baseURL: 'http://localhost:4000',
    timeout: 1000
})
//使用instance发请求
instance({
    url: '/index'
})

const instance2 = axios.create({
    baseURL: 'http://localhost:3000',
    timeout: 1000
})
//使用instance发请求
instance2({
    url: '/index'
})
4.拦截器

拦截器(回调函数) 注意:请求拦截器是先添加的后执行:响应拦截器是先写先执行

axios.interceptors.request.use(
    config => {
        return config
    },
    error => {
        return Promise.reject(error)
    })

//发送get请求
axios.get('接口')
    .then(response => {
    })
    .catch(error => {
        console.log(error)
    })
5.请求取消
let cancel   //用于保存取消请求的函数

axios({
    url: '',
    cancelToken: new axios.CancelToken(function (c) { //c是用于取消当前请求的函数
        cancel = c
    })
}).then(response => {
        cancel = null
    ...
    },
    error => {
        cancel = null
    ...
    })

if (typeof cancel === 'function') {
    cancel()
} else {
    console.log('没有可取消的请求')
}

请求取消案例: 两个请求,当点击第二个时取消第一个请求,

细节:错误的回调要将出错和取消请求的回调分开处理,取消的话不用使cancel函数为null,

原因:同步异步代码的执行顺序,当点第三次的时候取消不了第二次,因为后面的会先检查cancel是不是函数,如果是就给他覆盖了,最后导致取消函数失效

//定义一个函数cancel
let cancel = null

axios.interceptors.request.use(
    config => {
        if (cancel instanceof Function) {
            cancel()
        }
        config.cancelToken = new axios.CancelToken(function (c) { //c是用于取消当前请求的函数
            cancel = c
        })
        return config
    },
    error => {
        if (axios.isCancel(error)) {
            console.log('取消');
        } else {
            cancel = null
            console.log('请求出错');
        }
    }
)

function a1() {
    axios({
        url: 'xxx',
        /*cancelToken: new axios.CancelToken(function (c) { //c是用于取消当前请求的函数
            cancel = c
        })*/
    }).then(
        response => {
            console.log(response);
        }
    ).catch(
        error => {
            cancel = null
            console.log(error);
        })
}

function a2() {
    axios({
        url: 'xxx',
        /*cancelToken: new axios.CancelToken(function (c) { //c是用于取消当前请求的函数
            cancel = c
        })*/
    }).then(
        response => {
            console.log(response);
        }
    ).catch(
        error => {
            if (axios.isCancel(error)) {
                //如果是取消的话就不用把cancel设置为null,否则会影响下一下的取消
                console.log('取消');
            } else {
                cancel = null
                console.log('请求出错');
            }
        })
}

4.深入理解一些

axios与Axios的关系

1.从语法上来说,axios不是Axios的实例,因为axios是一个函数
2.从功能上来说,axios是Axios的实例,因为具有Axios的所有属性(defaults,interceptor),有Axios的原型上的方法
3.axios实际上是Axios.prototype.request方法.bind得来的

axios.js
var axios = creatInstance(config)

function creatInstance(config) {
    let context = new Axios(config)
//绑定request方法
    let instance = bind(Axios.prototype.request, context)
//调用extend方法copy Axios原型上的方法和Axios的属性到instance
    instance.extend(...return instance
}

axios.creat = ...
axios.creatToken=...
axios和instance的异同

同:

都是Axios.prototype.request函数通过修改this得来的
异:
instance没有axios后添加的creatToken,cancel,creat等方法

axios工作流程:

axios流程图

request串:
chain数组:[请求拦截器(先写后执行,unshift),dispatchRequest(),undefined 响应拦截器(先写先执行,因为在相应拦截器数组中是push)],通过promise链串联起来

dispatchRequest(config)
转换请求数据 => 调用xhrAdapter()发请求 => 请求返回后转换响应数据,返回promise

xhrAdapter(config)
创建xhr对象,根据config进行设置,发送特定请求,并接收响应数据,返回promise

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值