从 vue-cli 项目的接口调试出发
简单记录一下使用 vue-cli 构建的项目在本地开发环境下接口调试过程中遇到的一些问题。
一般情况下,本地开发环境中前端工程的端口号和后台接口的端口号不相同,举个简单的栗子:
在一个使用 vue-cli 构建的项目中,后端提供一个获取数据的接口 /get 和一个传输数据的接口 /send,端口号为8080,所以本地通过 http://localhost:8080/get 和 http://localhost:8080/send 请求这两个接口。
为了避免端口号冲突,我们配置 config/index.js 文件中 dev 下的端口号 port 为8686(保证不相同即可)。终端执行 npm run dev,本地通过 http://localhost:8686 访问该前端工程主页面,开始接口调试。
以 vue-resource 为例,请求 /get 和 /send 接口:
this.$http.get('/get', [options]).then(successCallback, errorCallback);
this.$http.get('/send', [options]).then(successCallback, errorCallback);
这么写的话会产生一个问题:发送请求时,将根据当前页面的根路径,请求路径被自动补全成 http://localhost:8686/get 和 http://localhost:8686/send,导致请求失败(因为后台接口的端口号为8080)。
解决该问题最简单粗暴的方法就是,在本地环境调试接口时写死请求路径,调试完成后再相应修改回去:
this.$http.get('http://localhost:8080/get', [options]).then(successCallback, errorCallback);
this.$http.get('http://localhost:8080/send', [options]).then(successCallback, errorCallback);
在以上基础下,可配置一个全局变量或者状态(使用 Vuex)对需要修改的根路径进行管理:
this.$http.get(origin + '/get', [options]).then(successCallback, errorCallback);
this.$http.get(origin + '/send', [options]).then(successCallback, errorCallback);
以上提到的方法都不推荐,一方面是太 low 了,另一方面是可能产生跨域问题。
推荐的解决方案是使用代理跨域。所谓代理就是代替前端发起 http 请求。在 vue-cli 项目中,可通过运行 npm run dev 后所启动的配置好的 node 服务器进行代理。
vue-cli 项目在本地开发环境调试接口时,可通过配置 proxyTable 实现代理跨域。相关文档 API Proxying During Development 以及 vue-cli 实现 proxyTable 所依赖的插件 http-proxy-middleware。
依旧接着上面的栗子,本地通过 http://localhost:8080/get 和 http://localhost:8080/send 请求 /get 和 /send 这两个接口,通过 http://localhost:8686 访问前端工程主页面。
那么我们在本地开发环境配置 config/index.js 文件中 dev 下的 proxyTable:
proxyTable: {
'/get': {
target: 'http://localhost:8080',
changeOrigin: true
},
'/send': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
proxyTable 可以理解成一个映射表,配置好之后需要重启 npm run dev 就实现代理跨域了。当我们本地请求 /get 和 /send 这两个接口:
this.$http.get('/get', [options]).then(successCallback, errorCallback);
this.$http.get('/send', [options]).then(successCallback, errorCallback);
node 服务器接收到我们的请求并代理到 http://localhost:8080,这样就不会存在跨域的问题了。
但是,根据上面写的 proxyTable 配置,如果我们再添加一个请求 /api 就需要对应地添加一条配置项,这样就又有点 low 了。
这时候我们可以使用参数 pathRewrite,其顾名思义“路径重写“。
我们先给需要代理的接口添加一个标识,比如 /mark。配置 proxyTable 根据标识 /mark 查找需要代理的接口,然后根据所配置的 pathRewrite 对标识 /mark 进行重写,重写成'',从而不影响所要请求的接口路径:
proxyTable: {
'/mark': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/mark': ''
}
}
}
为了方便,我们可以把标识配置成一个全局变量或者状态(使用 Vuex)进行管理。
this.$http.get(mark + '/get', [options]).then(successCallback, errorCallback);
this.$http.get(mark + '/send', [options]).then(successCallback, errorCallback);
当然,如果所有需要代理的接口已经有一个公共标识,这种情况可以不配置 pathRewrite 或者配置 pathRewrite 重写为本身。
以上就是 vue-cli 项目在本地开发环境中通过配置 proxyTable 实现代理跨域。
生产环境中,可通过 nginx 反向代理解决跨域问题。这方面本人没有深入了解,但是感觉原理应该是差不多的。