在最近的几次开发中,发现很多前端喜欢把线上API地址写为绝对路径,像这样:https://xx.com/api
这是不可取的,因为在生产实践中,一套代码会反复部署多个站点,如 https://a.com/api https://b.com/api 在这种情况下,前端会使用多个环境变量,.env.siteA, .env.siteB,乃至于.env.development, .env.production 打包时使用不同的命令:npm run build:a 以及 npm run build:b , npm run build:dev , npm run build:prod
除了在管理上繁琐,如果使用了多个API,这种情况会更棘手,比如在 A 站点,后端服务有 https://a1.com/api, https://a2.com/api ,这样无论如何都会出现跨域。在这种情况只好退而求其次,使用 http 协议规避跨域问题。
在写死域名的情况下,必须保证站点域名与API域名相同,实际上这种方案是错误的。因为站点域名,可以与API域名不一致,更不用说多个API域名了。
出现这种情况,前端往往要求后端解决跨域问题,说什么配置 nginx 头,完全是无稽之谈。
后端给出的解决方案是 nginx 子目录代理。
如:
location ^~ /api
{
proxy_pass https://a.com/api;
# 其他配置,如头,来源
}
注意后端是否要求消除 /api,如果需要消除,则应为:proxy_pass https://a.com/;
如果有多个后端API,则可以使用 /api1, /api2 这样的子路径配置,原理相同。
前端只需要写明,调用地址为 /api 即可,注意要在前端生产站点的nginx上做代理。
以下是一个典型配置,其中使用了两个 不同的API,以及一个websocket ,以及一个文件上传地址。
是的 websocket 也可以用 nginx 代理 。
VUE_APP_BASE_API = '/api'
VITE_APP_WEBSOCKET_URL = '/socket'
VITE_SERVER_BASEURL = '/wechatapi'
VITE_UPLOAD_BASEURL = '/wechatfile/fileUpload'
而本地调试,需要使用本地代理,此时的访问才是绝对地址,如:
proxy: {
// 配置代理
'/api': {
target: 'http://192.168.1.120:8080', // 开发调试
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '/'),
},
}
这样无论代码部署到哪个服务器,都不需要配置文件,打包只需要一个 npm run build 就可以了,根本不需要那么多配置文件,而调试时只需要 npm run serve ,走本地代理。
这才是最根本的跨域解决方案:服务器上用nginx代理,开发用本地代理