vue3+Ts 关于生成环境与开发环境请求路径问题

这里我是创建了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/;
        }
相关推荐
不吃鱼的羊17 分钟前
ISOLAR软件生成报错处理(七)
java·前端·javascript
TE-茶叶蛋41 分钟前
React-props
前端·javascript·react.js
安分小尧41 分钟前
[特殊字符] 超强 Web React版 PDF 阅读器!支持分页、缩放、旋转、全屏、懒加载、缩略图!
前端·javascript·react.js
EndingCoder43 分钟前
React从基础入门到高级实战:React 高级主题 - React Concurrent 特性:深入探索与实践指南
前端·javascript·react.js·前端框架
EndingCoder44 分钟前
React从基础入门到高级实战:React 生态与工具 - React Query:异步状态管理
前端·javascript·react.js·前端框架
TE-茶叶蛋1 小时前
ReactJS 中的 JSX工作原理
前端·react.js·前端框架
水煮白菜王1 小时前
React 编译器
前端·react.js·前端框架
霸王蟹1 小时前
React 项目中封装 Excel 导入导出组件:技术分享与实践
前端·笔记·学习·react.js·typescript·excel·vite
wl_1 小时前
react-color-palette源码解析
前端·react.js·调色板