当前位置: 首页 > 工具软件 > oauth-cli > 使用案例 >

vue-cli3 多环境和多后端的跨域代理配置 多种实现方案

寇夜洛
2023-12-01

大家都知道,由于3.x的默认配置都转移到了CLI service,所以生成的项目中并没有默认配置文件,所以我们如果需要自定义一些项目配置,则需要自己在项目的根目录创建一个vue.config.js

vue.config.js里的配置项所有都是可选的,这就避免了我们去看一大堆不必要的默认配置,只需要配置自己需要的部分就行了。

 

本文只对环境变量文件配置和跨域代理这一部分的配置进行分析和讲解。

 

vue.config.js:

首先,我们在vue.config.js文件中创建一个vueConfig 对象,并将其导出。

然后在vueConfig 对象里面再添加名为 devServer的key, 它的值也是一个对象。

const vueConfig = {
    devServer: {
        // development server port 8000
        port: 8000,
        // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
        proxy: {
          '/login': {
            target: process.env.VUE_APP_API_BASE_URL, // 需要代理的目标地址,一般是后端服务的ip:port。
            ws: false, // 是否需要开启webSocket
            secure: false,  // 如果是https接口,需要配置这个参数
            changeOrigin: true, // 设置为true, 本地就会虚拟一个服务器接收你的请求并代你发送该请求,这样就能跨域了
            // 路径重写
            pathRewrite: {
              "^/login": '/api/v1/login' // authorize, 如果你的后边还有路径的                
                                                               话, 会自动拼接上
            } // 如: '^/login‘ :表示 接口中的/login 会被替换成 /api/v1/login。 然后再加上target,完整的地址应该把是: ip:port/api/v1/login。 
          },
          '/oauth': {
            target: process.env.VUE_APP_API_BASE_URL,
            ws: false,
            secure: false,  // 如果是https接口,需要配置这个参数
            changeOrigin: true,
            // 路径重写
            pathRewrite: {
              "^/oauth": '/oauth' // 如果你的后边还有路径的话, 会自动拼接上
            },
          }
        }
      },
    }

里面其他的选项我们暂时不讲,着重讲代理的部分,也就是proxy。

proxy里一对key-value就是对一个后端地址的代理。

 

环境变量文件:

一般我们一个项目工程你可以建立四个环境变量文件:

.env文件:全局默认配置文件,不论什么环境都会加载合并

.env.development文件:开发环境下的配置文件

.env.production文件:生产环境下的配置文件

.evn.preview文件:生产环境预览下的配置文件,这个环境用的比较少

.env文件会根据你是开发环境还是生产环境来合并对应的变量。

所有环境变量文件内的属性名必须以VUE_APP_开头,比如VUE_APP_XXX

vue-cli会根据启动命令自动加载对应的环境,vue是根据文件名进行加载的,所以上面说“不要乱起名,也无需专门控制加载哪个文件”

比如执行npm run serve命令,会自动加载.env.development文件。npm run build会自动加载.env.production文件。

 

axios实例:

const service = axios.create({
  baseURL: (process.env.NODE_ENV === 'production' && baseConfig.gateway) ? process.env.VUE_APP_API_BASE_URL : '', // api base_url
  timeout: 20000, // 请求超时时间
  withCredentials: false
})

我们在创建axios时,其中有一个baseURL的配置项,这个配置项可以直接理解为是http请求地址的前缀。

 

其他配置:

const baseUrlPrefix = '/api/v1' // 除了baseURL外的通配前缀
const gateway = false // 是否走网关代理

 

了解了上面几个基础知识和配置,下面我们分三种环境来配置我们的跨域代理。

1. 本地开发环境:

开发环境时,跨域代理直接在vue.config.js中配置即可,target直接使用.env.development中配置的baseUrl就行

NODE_ENV=development
VUE_APP_PREVIEW=true
VUE_APP_API_BASE_URL='http://ip:port'

 注意,此时target已经配置了baseUrl,也就是前缀已经有了,axios实例中的baseURL就不需要配置了,直接填空‘’就行。

此时axios请求实例为: 

const systemRole = `${baseConfig.gateway ? baseConfig.baseUrlPrefix : ''}/authorize/systemRole`,
export function getSystemRoleList (parameter) {
  return axios({
    url: `${systemRole}s`,
    method: 'get',
    params: parameter
  })
}

其中/authorize会被devServer中配置的

pathRewrite: {
          "^/authorize": '/api/v1/authorize' // authorize, 如果你的后边还有路径的话, 会自动拼接上
        }

 中的'/api/v1/authorize'自动替换。

所以最终的请求url为:

http://ip:port/api/v1/authorize/systemRoles

 

2. 生产环境通过nginx代理:

由于vue.config.js中只能配置devServer,所以生产环境的代理并不能在此配置,所以我们一般生产环境都会打包部署到nginx服务器或者其他的代理服务器,这里以nginx代理举例。

同样,如果是nginx代理,axios实例依然不需要配置baseURL:

const service = axios.create({
  baseURL: (process.env.NODE_ENV === 'production' && baseConfig.gateway) ? process.env.VUE_APP_API_BASE_URL : '', // api base_url
  timeout: 20000, // 请求超时时间
  withCredentials: false
})

上面的 baseConfig.gateway表示走网关,nginx代理时,该值为false。

axios请求也一样,gateway为false时,url除了baseURL只需要带上‘/authorize’这条通用协议和后面的业务地址。

const systemRole = `${baseConfig.gateway ? baseConfig.baseUrlPrefix : ''}/authorize/systemRole`,
export function getSystemRoleList (parameter) {
  return axios({
    url: `${systemRole}s`,
    method: 'get',
    params: parameter
  })
}

nginx配置:


#user  nobody;
worker_processes  4;

error_log  /usr/local/nginx/logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid /program/nginx/nginx.pid;

events {
	use epoll;
	worker_connections  4096;
}


http {
	include mime.types;
	default_type  application/octet-stream;

	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
	'$status $body_bytes_sent "$http_referer" '
	'"$http_user_agent" "$http_x_forwarded_for"';

	access_log  /usr/local/nginx/logs/access.log  main;
        client_max_body_size 20M;
	sendfile on;
	#tcp_nopush on;

	#keepalive_timeout  0;
	keepalive_timeout  65;
	#request的header中包含’_’时,不忽略
	underscores_in_headers on; 

	gzip on;
	gzip_static on;
	gzip_proxied expired no-cache no-store private auth;
	gzip_disable "msie6"; #不使用gzip IE6
	gzip_min_length 1024; #gzip压缩最小文件大小,超出进行压缩(自行调节)
	gzip_buffers 4 16k; #buffer 不用修改
	gzip_comp_level 3; #压缩级别:1-10,数字越大压缩的越好,时间也越长
	gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 压缩文件类型
	gzip_vary off; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"
	

	 
	upstream authorize_{
		ip_hash;
		server 127.0.0.1:81;
	}
	upstream oauth_{
		ip_hash;
		server 127.0.0.1:88;
	}
	server {
		listen 80;
		server_name  localhost;

		#charset koi8-r;

		#access_log  logs/host.access.log  main;

		location / {
			root   /program/www/;
            index  index.html index.htm;
			try_files $uri $uri/ /index.html;
		}

		location /authorize{
			proxy_pass   http://authorize_/api/v1/authorize;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		location /oauth{
			proxy_pass   http://oauth_/oauth;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		error_page  404			  /404.html;

		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   html;
		}
	}
}

 很明显,nginx的配置和devServer的配置其实是一样的,所以可以理解为生产环境中nginx帮助做了开发环境devServer做的事情。

最终,请求的地址依然是:

http://ip:port/api/v1/authorize/systemRoles

3. 生产环境通过网关代理:

最后,如果生产环境不走nginx代理,而是用网关统一代理,那么我们这里devServer和nginx都不需要配置了。

直接把完整的请求地址传给网关服务器,剩下的工作交给网关自己来处理。

此时,gateway配置需要修改:

const baseUrlPrefix = '/api/v1'
const gateway = true

axios实例:

// 创建 axios 实例
const service = axios.create({
  baseURL: (process.env.NODE_ENV === 'production' && baseConfig.gateway) ? process.env.VUE_APP_API_BASE_URL : '', // api base_url
  timeout: 20000, // 请求超时时间
  withCredentials: false
})

baseURL此时需要配置网关服务器指定的地址.env.production:

NODE_ENV=production
VUE_APP_PREVIEW=false
VUE_APP_API_BASE_URL='http://gatewayAddress:port/XXX'

axios请求方法:

const systemRole = `${baseConfig.gateway ? baseConfig.baseUrlPrefix : ''}/authorize/systemRole`,
export function getSystemRoleList (parameter) {
  return axios({
    url: `${systemRole}s`,
    method: 'get',
    params: parameter
  })
}

此时由于gateway为true,所以需要在baseURL前面添加baseUrlPrefix :'/api/v1'

最后,axion请求的真实地址为:

http://gatewayAddress:port/api/v1/authorize/systemRoles

网关服务那边会识别这个地址,然后配置到你需要请求的真实的的地址上去。

 

以上就是三种环境或者代理模式下的跨域代理方式。

——end

欢迎留言交流。

 类似资料: