这里我是创建了axios 实例,通过axios 实例去请求后端,
javascript
// 创建axios实例
export const service:AxiosInstance = axios.create({
//请求地址
baseURL: (window as any).Config.BACKEND_URL, //import.meta.env.VITE_APP_BASE_API,
// 超时
timeout: 10000 * 20,
//请求头
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
});
baseURL是请求地址,调用axios /test 请求时,请求后端地址:请求地址/test
(window as any).Config.BACKEND_URL 外部配置文件,好处是当我们打包后,不用nginx
配置前端项目。可以直接用IIS(Internet Information Server)部署,然后请求后端地址就是(window as any).Config.BACKEND_URL配置里面的
import.meta.env.VITE_APP_BASE_API 是vue内部的生产环境和开发环境,根据环境不同,配置响应的拦截,请求后端
外部配置文件
public--static 创建config.js(项目打包后,会存在disr/static/文件夹下面)
javascript
window.Config = {
// 后台url
BACKEND_URL: 'http://192.168.xx.xx:xx/',
}
在项目的index.html 映入
javascript
<script src="/static/config.js"></script>
这样封装axios请求时就可以,使用外部配置文件,配置后端请求地址
开发环境
.env.development 文件
javascript
# 页面标题
VITE_APP_TITLE = 首页
# 开发环境配置
VITE_APP_ENV = 'development'
# 微信公众号/开发环境
VITE_APP_BASE_API = '/dev-api'
request.ts
javascript
import axios, { AxiosInstance, AxiosResponse }from "axios";
import { showNotify } from 'vant';
//引入store
import userStore from '@/store/userStore.ts'
const user = userStore();
// 创建axios实例
export const service:AxiosInstance = axios.create({
//请求地址
baseURL: import.meta.env.VITE_APP_BASE_API, //window.Config.BACKEND_URL
// 超时
timeout: 10000 * 20,
//请求头
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
});
// request拦截器,请求体加上token
service.interceptors.request.use(
(config: any) => {
// prettier-ignore
config.headers["Authorization"] = "Bearer" + user.token; // 让每个请求携带自定义token 请根据实际情况自行修改
return config;
},
(error) => {
Promise.reject(error);
}
);
//响应拦截
service.interceptors.response.use((res:AxiosResponse) => {
// 未设置状态码则默认成功状态
const code = res.data.code;
// 获取错误信息
// prettier-ignore
const msg = res.data.msg;
// 二进制数据则直接返回
// prettier-ignore
if (res.request.responseType === "blob" || res.request.responseType === "arraybuffer") {
return res.data;
};
//返回状态码判断
if (code === 401) {
// 说明不通过微信公众号调用
showNotify({ type: 'danger', message: '请关注微信公众号使用!',position: 'bottom', });
// prettier-ignore
return Promise.reject("请关注微信公众号!");
} else if (code === 500) {
showNotify({ type: 'danger', message: msg,position: 'bottom',});
return Promise.reject(new Error(msg));
} else if(code === 404) {
return res.data;
} else if(code === 201) { //没有数据
return res.data;
}else if(code !== 200){
showNotify({ type: 'danger', message: msg,position: 'bottom', });
return Promise.reject(new Error(msg));
}else{
return res.data;
}
}, (error) => {
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
showNotify({ type: 'danger', message: message ,position: 'bottom',});
} else if (message.includes("timeout")) {
message = "系统接口请求超时";
showNotify({ type: 'danger', message: message ,position: 'bottom',});
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
showNotify({ type: 'danger', message: message ,position: 'bottom',});
}
return Promise.reject(error);
});
//对外暴露
export default service;
最重要是:baseURL: import.meta.env.VITE_APP_BASE_API,
在vue.config.ts中配置启动端口,假设8000,当你定义request请求
javascript
export const test = async (cardId:string) => {
return await request({
url: '/test',
method: 'get',
})
}
你的请求并不是 ip地址:8000/test,而是 ip地址:8000/dev-api/test
另外假设我们在后端的求情地址是5002端口,需要访问后端/test路径,则需要配置代理
vue.config.ts
javascript
server: {
host: "0.0.0.0", // 默认为localhost
port: 5001, // 端口号
open: false, // 是否自动打开浏览器
// proxy:{}
proxy: {
// 本地开发环境通过代理实现跨域,生产环境使用 nginx 转发
"/dev-api": {
target: "http://localhost:5002", // 后端服务实际地址
changeOrigin: true,
//rewrite: (path) => path.replace(/^\/dev-api/, ""),
rewrite: path => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '')
},
},
},
意思是前端请求ip地址:8000/dev-api/test,会被代理拦截/dev-api/,去转发请求ip地址:5002/test,但是前端请求路径不会发生变化,任然是ip地址:8000/dev-api/test
生产环境
.env.production文件
javascript
# 页面标题
VITE_APP_TITLE = 首页
# 生产环境配置
VITE_APP_ENV = 'production'
# 微信公众号/生产环境
VITE_APP_BASE_API = '/prod-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
request封装类不变,当打包成dist文件夹,需要放荡nginx上,此时你的请求路径不是
不是nginx启动地址端口/test,也不是nginx启动地址端口/dev-api/test,而是
nginx启动地址端口/prod-api/test,那如何访问后端/test地址呢,我们需要配置nginx 代理拦截/prod-api,转发到我们后端
的IP地址端口
nginx.config
javascript
#分布式项目中,前端调用后端配置
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP &remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE_HOST $remote_addr;
proxy_pass http://127.0.0.1:8080/;
}