开发环境代理 proxy

前端项目本地开发过程中,常常会遇到跨域问题,这是因为我们的本地服务域名为localhost,而后端服务一般都是在后端服务器上,所以两个不同的域名之间通信就会存在跨域,严谨点来说是受同源策略的影响。

假设后端的完整 api 路径:https://pruduct.com/api/chat/user/list,前端在localhost下想要去访问这个 api

有个重要的前提是,后端需要在响应头设置'Access-Control-Allow-Origin': '*' ,该属性表示允许任何的源都有权限访问资源,*表示通配符。
如果后端没有设置这个属性,就算前端设置了本地代理proxy也是无法成功访问的。

后端设置了Access-Control-Allow-Origin后,其实本地可以不需要 proxy 也不会产生跨域问题,因为已经允许了任何源都有权限访问。

下面这个示例直接写死 baseURL 发起请求,不会跨域:

1
2
3
4
5
const request = axios.create({
baseURL: 'https://pruduct.com',
});

request('/api/chat/user/list');

那什么场景需要使用proxy代理呢?

以下场景,proxy就派上了用场:

  • 想在本地调用/打包不同环境的数据,不想手动修改 request baseURL
  • 本地需要同时调用多个服务(测试环境/正式环境,可能还有一些第三方环境)的接口,写死 baseURL无法满足要求

来看下如何使用proxy解决这两个问题

脚本调用/打包不同服务

如果不想手动修改 request baseURL,可以通过脚本调用不同的环境变量来实现,假如环境变量为API_BASE_URL

1
2
3
const request = axios.create({
baseURL: API_BASE_URL,
});
1
2
3
4
"scripts": {
"dev": "cross-env UMI_ENV=test max dev",
"dev:online": "cross-env UMI_ENV=online max dev",
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// .umirc.online.ts 生产环境配置文件
export default {
define: {
API_BASE_URL: 'https://pruduct.com', // 正式环境
},
};

// .umirc.test.ts 测试环境配置文件
export default {
define: {
API_BASE_URL: 'https://test.com', // 测试环境
},
};

同时调用多个服务

就好比想同时请求两个服务时,/api/user这个接口在https://pruduct.com下,/test/userhttps://test.com下,本地代理就派上用场了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const request = axios.create({
baseURL: '/',
})

proxy: {
'/api': {
target: 'https://pruduct.com',
changeOrigin: true,
},
'/test': {
target: 'https://test.com',
changeOrigin: true,
}
}

proxy 怎么用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
API_BASE_URL='https://pruduct.com'

// 组件发起请求
const request = axios.create({
baseURL: '/',
})
const apiUrl = '/api/user'
request(apiUrl)

proxy: {
'/api': {
target: API_BASE_URL,
changeOrigin: true,
},
}

发起/api/user请求时,匹配到 proxy 对象的路径/api后,那么实际请求地址为target + /api/user,即 https://pruduct.com + /api/user

应该有部分人以为 proxy 匹配路径必须是后端定义的,其实不是。
假设前端想自定义路径,或者说后端没有统一的路径,那么就可以自定义匹配路径

1
2
3
4
5
6
7
8
9
10
11
12
13
API_BASE_URL='https://pruduct.com'

// 组件发起请求
request('/customApiPrefix/api/user')

proxy: {
'/customApiPrefix': {
target: API_BASE_URL,
changeOrigin: true,
// 重写匹配的字段,如果不想出现在请求路径上,可以重写为""
pathRewrite: { "^/customApiPrefix": "" }
},
}

实际请求地址还是为https://pruduct.com + /api/user

小结:
开发过程中出现跨域是因为受同源策略的约束影响,localhost不能与后端服务通信,想要通信,后端需要设置允许请求的源'Access-Control-Allow-Origin': '*'。设置'Access-Control-Allow-Origin': '*'后,如果后端服务只有一个,可以写死baseUrl无需 proxy。如果有多个服务,那么通过proxy和环境变量的配置,可以让我们在开发或打包时更方便。

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×