Axios

第一章 HTTP相关

1.1 官方文档

Axios

1.2 HTTP请求基本过程

  1.  浏览器向服务器发送HTTP请求(请求报文)
  2. 后台服务器接收到请求后,处理请求,向浏览器端返回HTTP响应(响应报文)
  3. 浏览器接收到响应,解析显式响应体或调用回调函数

1.3 HTTP请求报文

        请求行

                格式:method url

                例如:GET/product_detail?id=2 或 POST/login

        请求头(一般有多个请求头)

                host:www.baidu.com

                Cookie:BAIDUID=AD3B0FA706E;BIDUPSID=AD3B0FA706;

                Content-Type:application/x-www-form-urlencoded 或者 application/json

        请求体

                name=lyc&pwd=123

                {"name":"lyc","pwd":123}

1.4 HTTP响应报文

        响应体

                格式: status statusText

                例如: 200 OK 或者 404 Not Found

        响应头(一般有多个)

                Content-Type:text/html;charset=utf-8

                Set-Cookie:BD_CK_SAM = 1;path=/

        响应体

                html/json/js/css/图片...

1.5 常见响应状态码

        200        OK                请求成功。一般用于GET与POST请求

        201        Created        已创建。成功请求并创建了新资源

        304        Not Modified 表示资源未修改过,是从浏览器缓存中直接拿取的

        401        Unauthorized        未授权/请求要求用户的身份认证

        404        Not Found        服务器无法根据客户端的请求找到资源

        500        Internal Server Error        服务器内部错误,无法完成请求

1.6 请求方式与请求参数

1.6.1 请求方式

  1. GET(索取):从服务器读取数据 ------ 查(R)
  2. POST(交差): 向服务器添加新数据 ------ 增(C)
  3. PUT:更新服务器端已存在的数据 ------ 改(U)
  4. DETELE:删除服务器端数据 ------ 删(D)

1.6.2 请求参数

        query参数(查询字符串参数)

  • 参数包含在请求地址中,格式为:/xxx?name=lyc&age=20
  • 敏感数据不要用query参数,因为参数是地址的一部分,比较危险
  • 备注:query参数又称查询字符串参数,编码方式为urlencoded

        params参数

  • 参数包含在请求地址中,格式如下:

        http://localhost:8080/add/lyc/20

  • 敏感数据不要用params参数,因为参数是地址的一部分,比较危险

1.6.3 请求体参数

        参数包含在请求体中,可通过浏览器开发者工具查看

        常用的两种格式

  • 格式一: urlencoded格式

                例如:name=lyc&age=20

                对应请求头:Content-Type:application/x-www-form-urlencoded

  • 格式二: json格式

                例如:{"name":"lyc","age":20}

                对应请求头:Content-Type:application/json

注意:

  • GET请求不能携带请求体参数,因为GET请求没有请求体
  • 理论上一次请求可以随意使用上诉3种类型参数中的任何一种,甚至一次请求的3个参数可以用3种形式携带,但是一般不这样做(脑子。。。)
  • 一般来说我们有一些"约定俗成"的规矩

        例如form表单发送post请求时:自动使用请求体参数,用urlencoded编码

  • 开发中请求到底发给谁?用什么请求方式?携带什么参数? ------- 参考项目API接口文档

第二章 API相关

2.1 API分类

2.1.1 REST API(restful风格的API)

  • 发送请求进行CRUD哪个操作由请求方式决定
  • 同一个请求路径可以进行多个操作
  • 请求方式会用到GET/POST/PUT/DELETE

2.1.2 非REST API(restless风格的API)

  • 请求方式不决定请求的CRUD操作
  • 一个请求路径只对应一个操作
  • 一般只有GET/POST

2.2 使用json-server搭建REST API

2.2.1 json-server是什么?

        用于快速搭建REST API的工具包

2.2.2 使用json-serve

  1. 在线文档https://github.com/typicode/json-server
  2. 下载:npm i -g json-server
  3. 目标目录下启动服务器执行命令: json-server db.json

        json文件名随意,可以直接打开创建的文件,修改里面的数据,直接使用

2.2.3 使用浏览器访问测试

        启动服务器后,可以复制生成的地址,测试一下接口,或者下面postman更高级。。

2.2.4 使用postman测试接口

        下载地址:Download Postman | Get Started for Free

2.2.5 一般http请求与ajax请求

  • ajax请求是一种特别的http请求
  • 对服务器端来说,没有任何区别,区别在于浏览器端
  • 浏览器端发请求:只有XHR或fetch发出的才是ajax请求,其他所有的都是非ajax请求
  • 浏览器端接收到响应:

        一般请求:浏览器一般会直接显示响应体数据,也就是我们常说的自动刷新/跳转页面

        ajax请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入响应相关数据

第三章 Axios的理解和使用

3.1 axios是什么?

        基于promise可以用于浏览器和node.js的网络请求库,在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

  1. 前端最流行的ajax请求库
  2. vue/react官方都推荐使用axios发ajax请求
  3. 官网Axios

3.2 axios特点

  • 基于promise的异步ajax请求库
  • 拦截请求和响应
  • 取消请求
  • 转换请求和响应数据
  • 自动转换JSON数据
  • 客户端支持防御XSRF
  • 批量发送多个请求

3.3 使用axios发请求

  1. axios调用的返回值是Promise实例
  2. 成功的值叫response,失败的值叫error
  3. axios成功的值是一个axios封装的response对象,服务器返回的真正的数据在response.data中
  4. 携带query参数时,编写的配置项叫做params(因为params英文意思有参数的意思),params参数直接写在请求路径上
  5. 如果需要携带params参数,需要自己拼接到url上

        开始发请求,可以先自己使用json-server开启一个服务器

3.3.1 发送GET请求

//不传参get,获取全部学生
<button id="btn1">获取学生信息</button>

const btn1 = document.getElementById('btn1')

btn1.onclick = function(){
    //完整写法
    axios({
        url: 'http://localhost:3000/xuesheng',    //请求地址
        method: 'GET'                             //请求方式
    }).then(
        response => { console.log('请求成功',response.data); },
        error => { console.log('请求失败',error); }
    )

    //别名写法
    axios.get('http://localhost:3000/xuesheng').then(
        response => { console.log('请求成功',response.data); },
        error => { console.log('请求失败',error); }
    )
}


//代码还可以更简,在这主要是演示一下两种写法
//这里举个例子
btn1.onclick = async () => {
    const result = await axios.get('http://localhost:3000/xuesheng')
        console.log(result.data);
}
//传idGET,获取某一个
<button id="btn2">获取某个学生信息</button>
<input type="text" id="person_id" placeholder="请输入一个人的id">

const btn2 = document.getElementById('btn2')
const personId = document.getElementById('person_id')

btn2.onclick = function(){
    //完整写法
    axios({
        url: 'http://localhost:3000/xuesheng',
        method: 'GET',
        //此处写的是params,但是携带的是query参数,因为params英文意思有参数的意思
        //get带参数都是在后面,如果不是拼在路径后,而是写成一个对象的,还必须加上params:{},
        //在params对象里写参数
        params: { id: personId.value } 
        }).then(
            response => { console.log('成功', response.data); },
            error => { console.log('失败', error); }
        )

    //别名
    axios.get(`http://localhost:3000/xuesheng?id=${personId.value}`
    //axios.get('http://localhost:3000/xuesheng',{
        //params:{id:personId.value}
    //})
    ).then(
        response => { console.log('成功', response.data); },
        error => { console.log('失败', error); }
    )
}

3.3.2 发送POST请求

const btn3 = document.getElementById('btn3')
const personName = document.getElementById('person_name')
const personAge = document.getElementById('person_age')

btn3.onclick = function(){
    //完整版
    axios({
        url: 'http://localhost:3000/xuesheng',
        method: 'POST',
        //携带请求体参数(json编码)
        //data: { name:personName.value, age:personAge.value }
        //携带请求体参数(urlencoded编码)  
        data: `name=${personName.value}&age=${personAge.value}` 
        }).then(
            response => { console.log('成功', response.data); },
            error => { console.log('失败', error); }
        // )

        //精简版
        axios.post('http://localhost:3000/xuesheng',
            //{ name: personName.value, age: personAge.value }).then(
            `name=${personName.value}&age=${personAge.value}`).then(
                response => { console.log('成功', response.data); },
                error => { console.log('失败', error); }
            )
}

3.3.3 发送PUT请求

<body>
    <button id="btn4">更新一个人</button>
    <input type="text" id="person_update_id" placeholder="请输入一个人的id">
    <input type="text" id="person_update_name" placeholder="请输入名字">
    <input type="text" id="person_update_age" placeholder="请输入年龄"><br>
</body>

<script>
    const btn4 = document.getElementById('btn4')
    const personUpdateId = document.getElementById('person_update_id')
    const personUpdateName = document.getElementById('person_update_name')
    const personUpdateAge = document.getElementById('person_update_age')

    btn4.onclick = function () {
        //完整写法
        axios({
            url: 'http://localhost:3000/xuesheng',
            method: 'PUT',
            data: {
                id: personUpdateId.value,
                name: personUpdateName.value,
                age: personUpdateAge.value
            }
        }).then(
            response => { console.log('成功', response.data); },
            error => { console.log('失败', error); }
        )

        //别名
        axios.put('http://localhost:3000/xuesheng', {
            id: personUpdateId.value,
            name: personUpdateName.value,
            age: personUpdateAge.value
        }).then(
            response => { console.log('成功', response.data); },
            error => { console.log('失败', error); }
        )
    }
</script>

3.3.4 发送DETELE请求

<body>
    <button id="btn5">删除一个人</button>
    <input type="text" id="person_detele_id" placeholder="请输入删除的id">
</body>

<script>
    const btn5 = document.getElementById('btn5')
    const personDeteleId = document.getElementById('person_detele_id')

    //删除一个人---detele---携带params参数
    btn5.onclick = function(){
        axios({
            url: `http://localhost:3000/xuesheng?${personDeteleId.value}`,
            method: 'DETELE',
        }).then(
            response => { console.log('成功', response); },
            error => { console.log('失败', error); }
        )
    }
</script>

3.4 axios常用配置项

           需要更详细,可以去官网

<button id="btn">点我获取</button>

const btn = document.getElementById('btn')

//常用配置项
btn.onclick = function () {
    axios({
        url: 'http://localhost:3000/xuesheng',
        method: 'GET',
        //params:{id:1},    //配置query参数
        //data: { a: 1, b: 2 },//配置请求体参数(json编码)
        //data: 'a=1&b=2',//配置请求体参数(urlencoded编码)
        //timeout: 2000,//配置超时时间
        //responseType: 'json',//配置响应数据的格式(默认值)
    }).then(
        response => { console.log('成功', response.data); },
        error => { console.log('失败', error); }
    )
}

3.5 axios全局配置项

        指定默认配置,它将作用于每个请求。

//按需求添加
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.timeout = 2000

3.6 axios.create方法

根据指定配置创建一个新的axios,也就是每个新axios都有自己的配置

  1. 新axios只是没有取消请求和批量发请求的方法,其他语法都是一致的
  2. 为什么要设计这个语法?项目中有部分接口需要的配置与另一部分接口需要的配置不太一样
const axios2 = axios.create({
  baseURL: 'https://api.example.com',
  timeout:2000
});

//创建完这个新的axios2,就可以用这个新的去发请求,每次请求都会带上上面的默认配置,
//解决上面的需求

3.7 axios请求拦截器和响应拦截器

        在请求或响应被 then 或 catch 处理前拦截它们

移除拦截器

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

3.7.1 请求拦截器

        在真正发请求前执行的一个回调函数

        对所有的请求做统一处理:追加请求头、追加参数、界面loading提示等

//语法
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}

3.7.2 响应拦截器

        得到响应之后执行的一个回调函数

//语法
axios.interceptors.response.use(
    function (response) {
        // 2xx 范围内的状态码都会触发该函数。
        // 对响应数据做点什么
        return response;
    }, 
    function (error) {
        // 超出 2xx 范围的状态码都会触发该函数。
        // 对响应错误做点什么
        return Promise.reject(error);
    }
);

        axios认为返回的不是2开头的状态码都是失败的

        不管请求成功还是请求失败都会先走响应拦截器的回调,然后根据响应拦截器的返回值,去调用请求时指定的回调,不过我们都会在响应拦截器失败的回调中,统一处理错误,返回pending状态的Promise,中断Promise链,一旦请求失败,我们中断了Promise链,就意味着我们在发请求时指定的回调是不会执行的

<button id="btn">获取</button>

const btn = document.getElementById('btn')

axios.interceptors.response.use(
    //根据请求成功或失败先走响应拦截器的相应回调
    function (response) {
        if(Date.now() % 2 === 0){
            return response.data
        }else{
            return '时间戳不是偶数,不能给你数据'
        }
    },
    function (error) {
            console.log('失败的回调执行了', error);
            //这里中断了Promise链,也就是当请求是失败的,就不会走下面的回调了
            return new Promise(() => { })
        }
    )

//btn.addEventListener('click', function () {
    //axios.get('http://localhost:3000/xuesheng').then(
        //不走
        //response => { console.log(response); },
        //error => { console.log('error'); }
    //)
//})

//所以就可以直接使用await,请求失败的响应拦截器会统一处理
btn.addEventListener('click', async function () {
    const result = await axios.get('http://localhost:3000/xuesheng')
    console.log(result);
})

3.8 取消请求

        从 v0.22.0 开始,Axios 支持以 fetch API 方式—— AbortController 取消请求,CancelToken此 API 从 v0.22.0 开始已被弃用。

        这个fetchAPI挺好看的,它会自动识别,失败原因是取消请求,还是请求失败,并在error.message中指出(canceled就是取消了的意思)

//这个是官方的,可以对比一下下面怎么使用
const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// 取消请求
controller.abort()


<body>
    <button id="btn">发请求</button>
    <button id="btn1">取消请求</button>
</body>
<script>
    const btn = document.getElementById('btn')
    const btn1 = document.getElementById('btn1')
    const controller = new AbortController();
    btn.addEventListener('click', function () {
        axios({
            url: 'http://localhost:3000/xuesheng',
            signal: controller.signal
        }).then(
            response => { console.log('成功', response.data); },
            error => { console.log('失败', error.message); }
        )
    })
    btn1.addEventListener('click', function () {
        controller.abort()
    })
</script>

3.9 Axios批量发请求

//这个是同时发多个
<button id="btn">同时发多次请求</button>

const btn = document.getElementById('btn')

//加一个响应拦截器处理一下数据
axios.interceptors.response.use(
    response => {
        return response.data
    },
    error => {
        return Promise.reject(error.message)
    }
)

btn.addEventListener('click', () => {
    axios.all([
        axios.get('http://localhost:3000/xuesheng'),
        axios.get('http://localhost:3000/xueli'),
        axios.get('http://localhost:3000/profile')
    ]).then(
        response => { console.log(response); },
        error => { console.log(error); }
    )
})



//这个是上一次请求成功,再发下一个,连着发
<button id="btn">批量发请求</button>

const btn = document.getElementById('btn')

btn.addEventListener('click', async () => {
    const result1 = await axios.get('http://localhost:3000/xuesheng')
    console.log(result1);
    const result2 = await axios.get('http://localhost:3000/xueli')
    console.log(result2);
    const result3 = await axios.get('http://localhost:3000/profile')
    console.log(result3);
})

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值