pocket-manual icon indicating copy to clipboard operation
pocket-manual copied to clipboard

从 vue-cli 项目的接口调试出发

Open FishPlusOrange opened this issue 7 years ago • 0 comments

简单记录一下使用 vue-cli 构建的项目在本地开发环境下接口调试过程中遇到的一些问题。

一般情况下,本地开发环境中前端工程的端口号和后台接口的端口号不相同,举个简单的栗子:

在一个使用 vue-cli 构建的项目中,后端提供一个获取数据的接口 /get 和一个传输数据的接口 /send,端口号为8080,所以本地通过 http://localhost:8080/gethttp://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/gethttp://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/gethttp://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 反向代理解决跨域问题。这方面本人没有深入了解,但是感觉原理应该是差不多的。

FishPlusOrange avatar Jun 04 '18 15:06 FishPlusOrange