背景
对于前后端分离项目,前端和后端端口不能重复,否则会导致前端或者后端服务起不来。例如前端访问地址为: 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. 创建 request.ts,创建axios实例
在项目根目录下,也就是src目录下创建文件夹api/,并创建request.js
,该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 = axios.create({
// 请求的域名,基本地址,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, // 每次调取接口的时间戳(秒级)
},
});
// 请求拦截器
$http.interceptors.request.use((config) => {
// 获取当前时间戳
const timestamp = parseInt(Date.now() / 1000);
const uuid = uuidv4(); // 生成UUID
console.log(parseInt(Date.now() / 1000),'3333333')
// console.log(config.method)
let signStr =config.method + config.url + uuid + timestamp + "Herdsric" + "Herdsric2024"
console.log('验签',signStr)
let mateApi = Md5.hashStr(signStr.toUpperCase());
console.log(mateApi)
config.headers['Lux-mateApiSignature'] = mateApi
config.headers['Lux-mateApiNonce'] = uuid //每次调取接口生成的uuid
config.headers['Lux-mateApiTimestamp'] = timestamp// 每次调取接口的时间戳(秒级)
config.headers = config.headers || {};
// if (localStorage.getItem("token")) {
// config.headers.token = localStorage.getItem("token") || "";
// }
return config;
});
// 响应拦截器
$http.interceptors.response.use((response) => {
return response;
}, (error) => {
ResponseProcessing(error);
});
/**
* 响应处理
* @param error
* @returns
*/
const ResponseProcessing = (error: { response: { state: any; data: any; }; }) => {
if (error.response) {
switch (error.response.state) {
case 401:
ElMessage.warning("资源没有访问权限!");
break;
case 404:
ElMessage.warning("接口不存在,请检查接口地址是否正确!");
break;
case 500:
ElMessage.warning("内部服务器错误,请联系系统管理员!");
break;
default:
return Promise.reject(error.response.data); // 返回接口返回的错误信息
}
} else {
ElMessage.error("遇到跨域错误,请设置代理或者修改后端允许跨域访问!");
}
};
export default $http;
在这里,我们自定义axois实例化对象,配置了默认的访问i后端ip和端口等,并在末尾使用export 导出api配置,便于在其他单文件中引入 request.ts.
3. 在main.ts中全局注册axios
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')
// createApp(App).use(router).mount('#app')
4. 创建api.ts文件夹
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 (response.data.code == 0) {
} else {
}
} catch (error) {
ElMessage.error("网络异常,请稍后再试");
console.error("There was an error fetching the data:", error);
}
};
4. 解决跨域问题。vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// import path from 'path';
// https://vitejs.dev/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)=>path.replace(/^\/api/,'') //api替换为'',
},
},
},
// resolve: {
// alias: {
// '@': path.resolve(__dirname, 'src'),
// },
// },
css: {
preprocessorOptions: {
less: {
additionalData: `@import "@/assets/style/base.less";`,
}
},
},
})
标签:Axios,http,跨域,示例,axios,error,import,config
From: https://blog.csdn.net/aaa123aaasqw/article/details/140150795