Vue使用axios二次封装、解决跨域问题

1、什么是 axios

在实际开发过程中,浏览器通常需要和服务器端进行数据交互。而 Vue.js 并未提供与服务器端通信的接口。从 Vue.js 2.0 版本之后,官方推荐使用 axios 来实现 Ajax 请求。axios 是一个基于 promise 的 HTTP 客户端。

关于 promise 的详细介绍,请点击浏览文章: 《ECMAScript6语法:Promise》

axios 的主要特点如下:

  • 从浏览器中创建 XMLHttpRequest。
  • 从 node.js 发出 HTTP 请求。
  • 支持 Promise API。
  • 拦截请求和响应。
  • 转换请求和响应数据。
  • 取消请求。
  • 自动转换JSON数据。
  • 客户端支持防止CSRF/XSRF。

官方文档: 《Axios中文文档》

2、安装 axios

如果在项目中使用 axios,则可以使用 npm 方式进行安装。在命令提示符窗口中输入如下命令:

java 复制代码
npm install axios --save

或者使用 yarn 安装,命令如下:

java 复制代码
yarn add axios --save

3、axios 的语法

在实际项目开发中,前端页面中所需的数据通常要从服务器端获取,这就需要实现本地与服务器端的通信,Vue 使用 axios 实现 Ajax 请求。

语法格式和参数说明:

javascript 复制代码
axios({
    url: '',             //请求的路径
    method: 'GET',       //请求的方式,默认为GET
    params: {},          //GET请求方式:传递的参数
    data: {},            //POST请求方式:传递的参数
    headers: {},         //自定义请求头
    timeout: 1000,       //请求超时时间(毫秒)
    responseType: 'JSON' //响应的数据类型,默认为JSON
}).then(
    // then() 函数:处理请求成功的回调函数
    function (response) {
        console.log("返回的数据", response.data);
    }
).catch(function (error) {
    // catch() 函数:处理请求失败的回调函数
    console.log("发生异常:" + error.message);
});

axios 详细使用方法,请点击浏览文章: 《Vue使用axios实现Ajax请求》

4、解决跨域问题

如果 Vue 前端应用请求后端 API 服务器,出现跨域问题(CORS),如下图:

**解决方法:**在 Vue 项目中,打开 vue.config.js 配置文件,在配置文件中使用代理解决跨域问题。

javascript 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    proxy: 'http://localhost:8085',  //使用代理,解决跨域问题
  }
})

详细的解决方法,请点击浏览文章: 《Vue使用代理方式解决跨域问题》

5、axios 的二次封装

在项目中,axios 进行二次封装可以更加方便的使用 Ajax 请求,提高代码复用性和维护性。同时可以封装统一的请求与响应拦截处理。

项目结构图:

5.1 封装 axios 公共处理类

在项目 src 目录下,创建 utils 目录,并在该目录下创建 request.js 类:

javascript 复制代码
// 1、引入axios
import axios from 'axios'

// 2、创建axios对象
const request = axios.create({
    //baseURL: 'http://localhost:8081', //注意:因为已经在 vue.config.js 文件中配置了代理服务(解决跨域问题),所有这里需要注释掉
    timeout: 0, //0表示永不超时
    withCredentials: true // 表示请求可以携带cookie   
});

// 3、添加请求拦截器
request.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 4、添加响应拦截器
request.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    if (response.status == 200) {
        return response.data;
    }
    else {
        alert("操作失败:" + response.data.message);
        return null;
    }
}, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
});

// 5、导出axios实例
export default request

5.2 创建 API 服务类

在实际项目中,为各个模块创建各自的 API 服务类,用于对接后端服务提供的 API 接口。

在项目 src 目录下,创建 API 目录,并在该目录下创建 UserApi.js 类:

javascript 复制代码
import request from '@/utils/request.js';

//获取用户信息
export function getUserInfo(userId) {
    return request({
        method: 'GET',
        url: `/user/getUserInfo/${userId}`
    });
}

//新增用户信息
export function saveUserInfo(userInfo) {
    return request({
        url: '/user/saveUserInfo',
        method: 'POST',
        data: userInfo
    });
}

//修改用户信息
export function updateUserInfo(userInfo) {
    return request({
        url: '/user/updateUserInfo',
        method: 'POST',
        data: userInfo
    });
}

//删除用户信息
export function deleteUserInfo(userId) {
    return request({
        url: `/user/deleteUserInfo/${userId}`,
        method: 'POST'
    });
}

5.3 创建组件并调用API接口

在项目 src 目录下,创建 views/user 目录,并在该目录下创建 UserInfo.vue 组件:

html 复制代码
<template>
    <fieldset>
        <legend>用户信息</legend>
        <p>用户名称:<input type="text" v-model="userInfo.userName" /></p>
        <p>用户年龄:<input type="text" v-model="userInfo.age" /></p>
        <p>用户性别:<input id="male" type="radio" value="男" v-model="userInfo.sex" />
            <label for="male">男</label>
            <input id="female" type="radio" value="女" v-model="userInfo.sex" />
            <label for="female">女</label>
        </p>
        <p>博客信息:<input type="text" v-model="userInfo.blogName" /></p>
        <p>博客地址:<input type="text" v-model="userInfo.blogUrl" /></p>
        <button @click="getUser(1)">查询用户</button>
        <button @click="saveUser">新增用户</button>
        <button @click="updateUser">修改用户</button>
        <button @click="deleteUser">删除用户</button>
    </fieldset>
</template>

<script setup>
//导入所需的API方法
import { getUserInfo, saveUserInfo, updateUserInfo, deleteUserInfo } from '@/api/UserApi.js';
import { ref } from 'vue';

//注意:这里使用 ref(),不要使用 reactive(),否则重新赋值后,响应式状态就缺失了
let userInfo = ref({
    userId: 0
});

//获取用户信息
function getUser(userId) {
    getUserInfo(userId).then(
        function (result) {
            userInfo.value = result;
        }
    );
}

//新增用户信息
function saveUser() {
    saveUserInfo(userInfo.value).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

//修改用户信息
function updateUser() {
    updateUserInfo(userInfo.value).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

//删除用户信息
function deleteUser() {
    deleteUserInfo(userInfo.value.userId).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

</script>

<!-- CSS样式 -->
<style scoped>
input[type="text"] {
    width: 300px;
    padding: 3px;
    font-size: 16px;
}

button {
    margin-right: 10px;
}
</style>

6、综合实例

通过上述 axios 的二次封装,下面通过一个综合实例,来测试应用效果。

**【实例】**使用 axios 的二次封装,通过使用 Ajax 请求,实现用户信息的查询、新增、修改、删除功能。实例执行的结果如下图:

使用 Java、SpringBoot 创建一个后端项目,编写 UserController.java 用户信息控制器,实现 API 接口。

java 复制代码
package com.pjb.pm.controller;

import com.pjb.pm.entity.UserInfo;
import org.springframework.web.bind.annotation.*;

/**
 * 用户信息控制器
 * @author pan_junbiao
 **/
@RestController
@RequestMapping("/user")
//@CrossOrigin //解决跨域问题
public class UserController
{
    /**
     * 获取用户信息
     */
    @RequestMapping(value = "/getUserInfo/{id}", method = RequestMethod.GET)
    public UserInfo getUserInfo(@PathVariable("id") Long userId)
    {
        //模拟用户查询功能
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName("pan_junbiao的博客");
        userInfo.setSex("男");
        userInfo.setAge(36);
        userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");
        userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
        return userInfo;
    }

    /**
     * 新增用户信息
     */
    @RequestMapping(value = "/saveUserInfo", method = RequestMethod.POST)
    public boolean saveUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo == null || userInfo.getUserName() == null || userInfo.getUserName().length() == 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }

    /**
     * 修改用户信息
     */
    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
    public boolean updateUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo.getUserId() <= 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }

    /**
     * 删除用户信息
     */
    @RequestMapping(value = "/deleteUserInfo/{id}", method = RequestMethod.POST)
    public boolean deleteUserInfo(@PathVariable("id") Long userId)
    {
        if (userId == 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }
}

执行结果:

(1) 查询用户信息:

(2)新增、修改、删除用户信息:

相关推荐
梅秃头3 分钟前
vue2+elementUI实现handleSelectionChange批量删除-前后端
前端·javascript·elementui
请叫我欧皇i6 分钟前
el-form动态标题和输入值,并且最后一个输入框不校验
前端·javascript·vue.js
工业互联网专业7 分钟前
毕业设计选题:基于ssm+vue+uniapp的驾校预约管理系统小程序
vue.js·小程序·uni-app·毕业设计·ssm·源码·课程设计
工业互联网专业22 分钟前
毕业设计选题:基于ssm+vue+uniapp的面向企事业单位的项目申报小程序
vue.js·小程序·uni-app·毕业设计·ssm·源码·课程设计
小小李程序员33 分钟前
css边框修饰
前端·css
我爱画页面1 小时前
使用dom-to-image截图html区域为一张图
前端·html
忧郁的西红柿1 小时前
HTML-DOM模型
前端·javascript·html
思茂信息1 小时前
CST电磁仿真77GHz汽车雷达保险杠
运维·javascript·人工智能·windows·5g·汽车
bin91531 小时前
【油猴脚本】00010 案例 Tampermonkey油猴脚本,动态渲染表格-添加提示信息框,HTML+Css+JavaScript编写
前端·javascript·css·bootstrap·html·jquery