Vue3全局配置Axios并解决跨域请求问题示例详解

时间:2025-03-09 20:22:03

背景

对于前后端分离项目,前端和后端端口不能重复,否则会导致前端或者后端服务起不来。例如前端访问地址为: http://localhost:8080/ ,后端访问地址为 http://localhost:8081/ 。后端写好Controller,当用Axios访问该接口时,将会报错:

Access to XMLHttpRequest at ' http://localhost:8081/login ' from origin ' http://localhost:8080 ' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

本文内容从axios部署开始到解决跨域问题。

前端: Vue3;Axios 1.6.0 ;Element-Plus
后端:Springboot 2.7.14

这里提供两种解决方案,都是基于后端跨域访问的配置,前端不作任何允许跨域访问的设置,因为试过无效。

一、部署Axios

Axios的基本介绍:
(1)axios 是一个基于promise的HTTP库,支持promise所有的API
(2)浏览器端/node端(服务器端)都可以使用,浏览器中创建XMLHttpRequests
(3)支持请求/响应拦截器
(4)它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
(5)批量发送多个请求
(6)安全性更高,客户端支持防御XSRF

1. npm 安装 axios

npm install axios

2. 创建 ,创建axios实例

在项目根目录下,也就是src目录下创建文件夹api/,并创建 ,该js用于创建axios实例。

import axios from 'axios';
import { ElMessage } from 'element-plus';
import { v4 as uuidv4 } from "uuid";

//ts使用
import { Md5 } from "ts-md5";


// 创建axios实例
const $http = ({
  // 请求的域名,基本地址,proxy 代理时会将“/api”以及前置字符串会被替换为真正域名
   baseURL: '/api',
  // 跨域请求时发送Cookie
  withCredentials: true, // 视情况而定
  // 超时时间
  timeout: 5000,
  headers: {
    // 设置后端需要的传参类型
    'content-type': 'application/json; charset=utf-8',
    // "Lux-mateApiNonce": uuid, //每次调取接口生成的uuid
    // "Lux-mateApiSignature": mateApi, //md5(method+requestURI+nonce+timestamp+appId+appSecret)
    // "Lux-mateApiTimestamp": timestamp, // 每次调取接口的时间戳(秒级)
  }, 
});

// 请求拦截器
$((config) => {
    // 获取当前时间戳
    const timestamp = parseInt(() / 1000);
    const uuid =  uuidv4(); // 生成UUID
    (parseInt(() / 1000),'3333333')
    // ()
    let signStr = +  + uuid + timestamp + "Herdsric" + "Herdsric2024"
    ('验签',signStr)
    let mateApi = (());
    (mateApi)
    ['Lux-mateApiSignature'] = mateApi
    ['Lux-mateApiNonce'] = uuid //每次调取接口生成的uuid
    ['Lux-mateApiTimestamp'] = timestamp// 每次调取接口的时间戳(秒级)
     =  || {};
    // if (("token")) {
    //      = ("token") || "";
    // }
    return config;
  });
  
  // 响应拦截器
  $((response) => {
    return response;
  }, (error) => {
    ResponseProcessing(error);
  });
  
  /**
   * 响应处理
   * @param error 
   * @returns 
   */
  const ResponseProcessing = (error: { response: { state: any; data: any; }; }) => {
    if () {
      switch () {
        case 401:
          ("资源没有访问权限!");
          break;
        case 404:
          ("接口不存在,请检查接口地址是否正确!");
          break;
        case 500:
          ("内部服务器错误,请联系系统管理员!");
          break;
        default:
          return (); // 返回接口返回的错误信息
      }
    } else {
        ("遇到跨域错误,请设置代理或者修改后端允许跨域访问!");
    }
  };
  
  export default $http;

在这里,我们自定义axois实例化对象,配置了默认的访问i后端ip和端口等,并在末尾使用export 导出api配置,便于在其他单文件中引入 .

3. 在中全局注册axios

import { createApp } from 'vue'
import './'
import App from './'
import router from './router'

import ElementPlus from 'element-plus'
import 'element-plus/dist/'


const app = createApp(App)
(ElementPlus)
(router)
('#app')
// createApp(App).use(router).mount('#app')

4. 创建文件夹

import $http from './Interceptor';

export function getTestData(params: any) {
    return $http({
      url: '/',
      method: 'get',
      params
    })
  }

4. 在页面中使用axios

import { getTestData } from "../http/API";
const fetchUserData = async () => {
  try {
    let params = {
      
    };
    const response = await getTestData(params);
    if ( == 0) {
     
    } else {
     
    }
  } catch (error) {
    ("网络异常,请稍后再试");
    ("There was an error fetching the data:", error);
  }
};

4. 解决跨域问题。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// import path from 'path';

// /config/
export default defineConfig({
  plugins: [vue()],
    // 解决跨域问题
  server: {
    host: '0.0.0.0',
    // port: 4000,
    proxy: {
      '/api': {
        target: 'http://192.168.31.17:4000',
        // secure: false, // 请求是否为https
        changeOrigin: true,
        rewrite:(path)=>(/^\/api/,'') //api替换为'',
      },
    },
  },



  // resolve: {
  //   alias: {
  //     '@': (__dirname, 'src'),
  //   },
  // },
  css: {
    preprocessorOptions: {
      less: {
        additionalData: `@import "@/assets/style/";`,
      }
    },
  },
})