vue项目 Axios创建拦截器

Axios

    • [1. Axios 和 Ajax 简介](#1. Axios 和 Ajax 简介)
    • [2. Axios 和 Ajax 的区别](#2. Axios 和 Ajax 的区别)
    • [3. 从 按钮 到 Axios请求后端接口的 大致顺序](#3. 从 按钮 到 Axios请求后端接口的 大致顺序)

1. Axios 和 Ajax 简介

Ajax(Asynchronous JavaScript and XML) 不是一种技术,而是一个编程技术概念,核心是通过 XMLHttpRequest 对象实现异步通信。

Axios 是一个独立的库,它既在浏览器环境中使用了 XMLHttpRequest,又在服务端使用 原生node.js http 模块。

2. Axios 和 Ajax 的区别

特性 原生 Ajax(XMLHttpRequest) Axios
使用方式 需要手动创建 和 管理 XMLHttpRequest 对象 提供简洁的 API,如 axios.get()axios.post()
异步处理 使用回调函数 基于 Promise,支持 async/await
功能扩展 功能有限,需手动实现 内置拦截器、请求取消、自动转换 JSON 等功能
跨平台支持 仅限浏览器 支持浏览器和 Node.js

3. 从 按钮 到 Axios请求后端接口的 大致顺序

  1. 点击按钮

    点击按钮时,触发 @click 点击事件,就到了 login 函数。

    javascript 复制代码
    <!-- 登录按钮 -->
    <el-form-item>
        <el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
    </el-form-item>
  2. login里请求接口的函数,写在了 user.js 文件中

    示例代码

    javascript 复制代码
    import { userLoginService } from '@/api/user.js'
    import { ElMessage } from 'element-plus'
    
    //导入路由 router
    import {useRouter} from 'vue-router'
    const router = useRouter();
    
    //导入 有Pinia函数的token.js文件
    import { useTokenStore } from '@/stores/token'
    const tokenStore = useTokenStore();
    
    //登录函数 login
    const login = async () => {
        //调用接口,完成登录
        let result = await userLoginService(registerData.value);
        //alert(result.msg ? result.msg : '登录成功');
        ElMessage.success(result.msg ? result.mag : '登录成功');
    
        //把得到的token存储到pinia中
        tokenStore.setToken(result.data);
    
        //跳转到首页,使用useRouter切换组件,完成跳转
        router.push('/');
    }
  3. 在 user.js 里的请求,都统一用 request.js 请求工具来完成

    示例代码

    javascript 复制代码
    //导入request.js请求工具
    import request from '@/utils/request.js'
    
    //提供调用主次接口的函数
    export const userRegisterService = (registerData) => {
        //借助于UrlSearchParams完成传递
        const params = new URLSearchParams();
        for (let key in registerData) {
            params.append(key, registerData[key]);
        }
        return request.post('/user/register', params);
    }
    
    export const userLoginService = (loginData) => {
        const params = new URLSearchParams();
        for (let key in loginData) {
            params.append(key, loginData[key])
        }
        return request.post('/user/login', params);
    }
  4. 在请求工具 request.js 里,导入了Axios,并创建了请求拦截器响应拦截器

    有了拦截器 ,就可以在 请求服务前得到响应后 统一处理数据。

    示例代码:

    javascript 复制代码
    //这里边相当于请求的工具,用来定制请求的实例
    
    //导入axios: npm install axios
    import axios from 'axios';
    
    //导入Message消息提示
    import { ElMessage } from 'element-plus';
    
    //定义一个变量,记录公共的前缀,baseURL
    // const baseURL = 'http://localhost:8080';
    // 这里的'/api'只是给后台访问的请求路径添加一个标识
    const baseURL = '/api';
    
    /*  axios.create()方法,把baseURL作为参数传入,
        该方法返回一个请求的实例instance,
        以后发送请求时,就不用axios.get了,
        直接用instance.get就可以 */
    const instance = axios.create({ baseURL })
    
    /* axios提供的拦截器,
        在请求或响应,被then或catch处理前拦截
        也就是在请求发出之前,有一个请求拦截器
        或在响应到达之前,有一个响应拦截器 */
    
    
    //导入Pinia
    import { useTokenStore } from '@/stores/token';
    //添加请求拦截器
    instance.interceptors.request.use(
        (config) => {
            //请求前的回调
            const tokenStore = useTokenStore();
            //在pinia中定义的响应式数据,都不需要.value
            if (tokenStore.token) {
                config.headers.Authorization = tokenStore.token;
            }
            return config
        },
        (err) => {
            //请求错误的回调
            Promise.reject(err);
        }
    )
    
    /* 由于模块加载的顺序,不能这样导入
        import { useRoute } from 'vue-router';
        const router = useRoute(); 
    */
    //这样导入就能用了
    import router from '@/router'
    
    //添加响应拦截器(这个拦截器本身就是异步的)
    instance.interceptors.response.use(
        //成功的回调
        result => {
            //判断业务状态码
            if (result.data.code === 0) {
                return result.data;
            }
    
            //操作失败
            ElMessage.error(result.data.msg ? result.data.msg : '服务异常');
    
            //异步操作的状态转换为失败
            return Promise.reject(result.data);
        },
        //失败的回调
        err => {
            //判断响应状态码,若为401,则说明未登录,提示请登录,并跳转到登录页面
            if(err.response.status === 401){
                ElMessage.error('请先登录');
                router.push('/login');
            }else{
                ElMessage.error('服务异常');
            }
    
            //异步的状态转化成失败的状态
            return Promise.reject(err);
        }
    )
    
    //把请求的实例instance导出,供其他地方调用
    export default instance;

    上述代码中的 const baseURL = '/api' ,在另一篇文章 vue处理跨域问题 里有详细描述。

相关推荐
PuddingSama几秒前
Compose Indication 实现点击效果
android·前端
可缺不可滥13 分钟前
微前端 无界wujie
前端·微前端·无界·wujie
Three~stone30 分钟前
Vue学习笔记集--scoped组件
vue.js·笔记·学习
zheshiyangyang39 分钟前
Flask+Vue-Router+JWT实现登录验证
vue.js·python·flask
巴巴博一39 分钟前
前端安全之DOMPurify基础使用
前端·vue.js·安全·typescript·html5
纸上的彩虹1 小时前
AI干不掉程序员,但却能让一个程序员干两个程序员的活儿~
前端·github copilot·ai 编程
码农不惑1 小时前
Qt开发:QtWebEngine中操作选择文本
开发语言·javascript·qt·web
SunshineBrother1 小时前
iOS项目,shell脚本,从大到小打印图片占用内存大小
前端
二川bro1 小时前
前端内存优化实战指南:从内存泄漏到性能巅峰
前端
疏狂难除1 小时前
基于SeaORM+MySQL+Tauri2+Vite+React等的CRUD交互项目
前端·react.js·前端框架