proxyTable的探究
最近在使用vue、express和mongodb在本地做一个前后端分离的移动端项目,前端页面用vant组件库简单拼了几个页面之后,想把前后端连接起来。于是用express写了接口,这个时候如果直接在前端页面中请求是不行的,会存在跨域问题。查了一下资料,可以利用webpack初始化的vue项目里的proxyTable来解决这个问题。
一、配置后端接口
- 创建app.js并配置接口
var express = require('express');
var app = express();
//返回数据
var users=[
{ name: 'xiaoma', age: 20 },
{ name: 'xiaoming', age: 18 }
];
app.get('/test',function(req,res){
res.status(200),
res.json(users)
});
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
复制代码
- 运行上面的文件
node app.js
复制代码
- 在浏览器中输入
http://localhost:3000/test
,结果:
二、请求接口
1.在vue文件中发送http请求
<template>
...
</template>
<script>
...
created() {
this.getData();
},
methods: {
getData(){
Vue.axios.get('http://localhost:3000/test').then((response) => {
console.log(response.data)
})
}
},
};
</script>
<style>
...
</style>
复制代码
- 打开vue页面,结果:
很明显,如果像上面这样子直接在vue页面中请求这个接口,是访问不了的,会报Access-Control-Allow-Origin
错误,因为存在同源策略,协议、域名、端口其中有一个不同都会出现这种跨域问题。
三、使用proxyTable解决跨域
解决跨域有很多方法,我这里使用的是webpack初始化的vue项目,项目目录里config文件夹中的index.js内有一个配置项 proxyTable 就是用来解决上面提到的跨域问题。
- 配置proxyTable
未修改过的proxyTable默认是这样的:
proxyTable: {}
复制代码
修改如下:
proxyTable: {
'/api': {//虚拟目录
target: 'http://localhost:3000', //要请求的目标服务器
changeOrigin: true, //设置为true, 代表开启代理
pathRewrite: {
'^/api': '' //重写路径,将/api路径重命名为 ''
}
}
}
复制代码
- 修改请求函数
getData(){
Vue.axios.get('/api/test').then((response) => {
console.log(response.data)
})
}
复制代码
我们重新刷新一下vue页面,会发现能够正常拿到接口返回的数据
3.原理
同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。vue-cli的proxyTable
用的是http-proxy-middleware中间件,该中间件本质上是在本地开了一个服务器dev-server
,所有的请求都通过这里转发出去,即把浏览器的发送请求代理转发到代理服务器上,再由代理服务器发送请求给目标服务器,从而解决跨域问题。
如上面那张图,通常代理服务器需要做以下几个步骤:
- 接受客户端请求
- 将请求转发给服务器
- 拿到服务器响应数据
- 将响应转发给客户端
四、最后
遇到跨域问题的场景有很多,只要是做前端开发,总会遇到。解决方案也是多种多样,如jsonp、cors、websocket、nginx反向代理,也包括上面用到的node中间件代理,等等,各有差异。在实际开发中,更多是使用代理来避免同源策略。