Skip to content

axios

axios的中文读音是爱克丝伊欧姿,它是一个非常流行的JavaScript库,用于进行HTTP请求。它提供了一种方便、简洁的方式来与服务器进行通信,并处理异步请求和响应。通过使用axios,开发人员可以轻松地发送GETPOSTPUTDELETE等类型的请求。

安装axios

powershell
npm i axios

发起请求

这里假设我们后端服务地址为:http://xxx.com,此服务地址拥有一个restful协议的api/user

get请求

typescript
    const id=1;
    axios.get('http://xxx.com/user');//无参数 或固定参数写法
    axios.get(`http://xxx.com/user?id=${id}`);// 有参写法一
    // 有参写法二
    axios.get('http://xxx.com/user', {
        params: {
            id
        }
    });

post请求

typescript
    const id = 1;
    const name = '李雷';
    axios.post('http://xxx.com/user');//无参数 或固定参数写法
    axios.post(`http://xxx.com/user?id=${id}`);// 有参写法一
    // 有参写法二
    axios.post('http://xxx.com/user',{name});
    // 有参写法三
    axios.post(`http://xxx.com/user?id=${id}`, { name });
    // 有参写法三
    axios.post('http://xxx.com/user', { name }, {
        params: {
            id
        }
    });

put请求

post请求行为一致,只需要把post换成put就行

typescript
    const id = 1;
    const name = '李雷';
    axios.put('http://xxx.com/user');//无参数 或固定参数写法
    axios.put(`http://xxx.com/user?id=${id}`);// 有参写法一
    // 有参写法二
    axios.put('http://xxx.com/user',{name});
    // 有参写法三
    axios.put(`http://xxx.com/user?id=${id}`, { name });
    // 有参写法三
    axios.put('http://xxx.com/user', { name }, {
        params: {
            id
        }
    });

delete请求

与get请求行为一致,只需要把get改成delete即可

typescript
    const id=1;
    axios.delete('http://xxx.com/user');//无参数 或固定参数写法
    axios.delete(`http://xxx.com/user?id=${id}`);// 有参写法一
    // 有参写法二
    axios.delete('http://xxx.com/user', {
        params: {
            id
        }
    });

跨域处理

虽然我们刚才的请求地址和请求参数都是正常的,但是控制台却提示如下错误:

powershell
Access to XMLHttpRequest at 'http://xxx.com/user?id=1' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

这是因为我们的网络请求跨域了,所以我们需要通过代理去解决跨域问题

修改vite.config.ts,添加如下代码

typescript
    server: {
      proxy: {
        '/api': {
          target: `http://xxx.com`, // 后端服务实际地址
          changeOrigin: true, //开启代理,
          rewrite: (path) => path.replace(/^\/api/, '')//重写path,将api前缀删掉
        }
      },
    }

然后我们再请求接口的时候只需要写接口的path就可以了,例如

typescript
axios.get('/api/user');

接收响应结果

可以使用thencatch,finally来根据情况进行数据处理

typescript
    axios.get('/api/user').then(res => {
        // 处理成功情况  
        console.log(res);
    }).catch(err => {
        // 处理错误情况  
        console.log(err);
    }).finally(() => {
        // 总是会执行
    })

注册登录案例

vue
<template>
    <div>
        <el-form>
            <el-form-item label="用户名">
                <el-input v-model="user_name"></el-input>
            </el-form-item>
            <el-form-item label="密码">
                <el-input v-model="user_pass" type="password"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button @click="register">注册</el-button>
                <el-button @click="login">登录</el-button>
            </el-form-item>
        </el-form>
    </div>

</template>
<script lang="ts" setup>
import { ElButton, ElForm, ElFormItem, ElInput,ElMessage } from 'element-plus'
import axios from 'axios';
import { ref } from 'vue';
interface IRes{
    code:number,
    msg:string,
    data:any
}
const user_name = ref('');
const user_pass = ref('');
const register = () => {
    axios.post<IRes>('/api/register',{
        userName:user_name.value,
        userPass:user_pass.value
    }).then(res => {
        if(res.data.code === 0){
            ElMessage.success(res.data.msg);
            // 写一些注册成功后的逻辑
        }
        else {
            ElMessage.error(res.data.msg);
        }
    })
}
const login = () => {
    axios.post<IRes>('/api/login',{
        userName:user_name.value,
        userPass:user_pass.value
    }).then(res => {
        if(res.data.code === 0){
            ElMessage.success(res.data.msg);
            // 写一些登录成功后的逻辑
        }
        else {
            ElMessage.error(res.data.msg);
        }
    })
}
</script>

封装一个自己的request

观察我们上面的代码,我们目前已知后端服务返回的数据格式如下

typescript
{
    code:number,
    msg:string,
    data:any
}

我们每个接口的写了类似如下的代码片段

typescript
        if(res.data.code === 0){
            ElMessage.success(res.data.msg);
            // 写一些成功后的逻辑
        }
        else {
            ElMessage.error(res.data.msg);
        }

除了code等于0时代表成功1代表失败,我们真实的业务可能还会有:

  • 404:跳转到404页面
  • 401:未授权,跳转到登录页面
  • 403:没有权限,拒绝访问

等等很多业务状态码,我们每个接口都写一遍显然是不现实的。

还有一些情况就是我们有很多接口是需要带token的,每个接口都去获取token并且传给后端这也不合理的

所以我们可以封装一个自己的request统一进行处理

可以在src目录下新建一个utils文件夹,再新建一个文件,命名为request.ts

typescript
import axios from 'axios';
import { ElMessage } from 'element-plus';
const service = axios.create({
    timeout: 30000 //接口响应超时时间
});

//请求拦截器
service.interceptors.request.use(
    (config) => {
        // 模拟token
        config.headers['Authorization'] = 'Bear asdfghjkl';
        return config;
    },
    (error) => {
        Promise.reject(error);
    }
);

// 响应拦截器
service.interceptors.response.use(
    (res): any => {
        // 未设置状态码则默认成功状态
        const code = res.data.code;
        if (code === 401) {
            ElMessage.error('未授权请登录');
            // 跳转到登录页
        } else if (code !== 0) {
            ElMessage.error(res.data.msg);
            return Promise.reject(res);
        }
        return Promise.resolve(res);

    },
    (error) => {
        const { message } = error;
        ElMessage({
            message: message,
            type: 'error',
            duration: 5 * 1000
        });
        return Promise.reject(error);
    }
);
export default service;

再次使用时,使用request代替axios即可

typescript
import request from '@/utils/request';
const register = () => {
    request.post<IRes>('/api/register', {
        userName: user_name.value,
        userPass: user_pass.value
    }).then(res => {
        ElMessage.success(res.data.msg);
        // 写一些注册成功后的逻辑

    })
}