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 分钟前
C++、Ruby和JavaScript
java·开发语言·javascript·c++·python·c·ruby
Front思18 分钟前
vue使用高德地图
javascript·vue.js·ecmascript
zqx_71 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己1 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称2 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色2 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css
NiNg_1_2342 小时前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦2 小时前
如何在 Axios 中封装事件中心EventEmitter
javascript·http