Proxy跨域
跨域现象只出现在浏览器,服务端和服务端之间是不存在跨域的。
什么是跨域
主要是出于浏览器的同源策略限制,它是浏览器最核心也是最基本的安全功能。
当请求url的协议、域名、端口号三者任意一个与当前页面url不一致即为跨域。
例如:
- http:www.123.com 去请求 https:www.123.com 因为协议不一致,造成了跨越。
- http:www.123.com 去请求 http:www.456.com 因为域名不一致,造成了跨域。
- http:www.123.com:80 去请求 http:www.123.com:8080 因为端口号不一致,造成了跨域。
解决跨域
JSONP
jsonp这种方式在之前很常见,利用了HTML中的<script>元素标签没有跨域限制,动态创建<script>标签,将src作为服务器的地址,服务器返回一个callback接收返回的参数,但是jsonp只能发送GET请求。
// 按钮点击事件的处理函数
function btnHandler () {
let param, script;
param = { "pageNo": 1, "pageSize": 10 } // 请求参数
script = document.createElement('script') // 创建script标签
script.src = '接口地址'
document.appendChild(script)
}
// 与后端商量好的callback名称
function myFunction (myObj) {
// 接收后端返回的参数
document.getElementById('dome').innerHTML = mayObj
}
CORS
设置CORS允许跨域资源共享,需要后端才能设置。
{
"Access-Control-Allow-Origin": "*" // 表示允许任何地址访问
"Access-Control-Allow-Origin": "http:xxx.com" // 表示允许指定地址访问
}
Proxy(代理)
使用Vite Proxy或者node 代理或者webpack Proxy三种方式都是代理。
Vite Proxy:
export default ({ mode }) => {
console.log(loadEnv(mode, process.cwd()));
return defineConfig({
server: {
proxy: {
// 请求路径遇到有api的就进行代理转发请求
'/api': {
target: 'http://xxx:9999', // 接口的请求根地址
rewrite: (path) => path.replace(/^\/api/, '') // 路径重写
}
}
},
})
}
比如说我Vue项目的开发服务器地址是:http://localhost:8080。
后端给的获取列表数据的接口根地址是:http://192.168.13.11:9999/sys/getList。
那么我们就可以这样写代理:
export default ({ mode }) => {
console.log(loadEnv(mode, process.cwd()));
return defineConfig({
server: {
proxy: {
// 请求路径的前缀为api的就进行代理转发请求
'/api': {
target: 'http://192.168.13.11:9999', // 接口的请求根地址
rewrite: (path) => path.replace(/^\/api/, '/sys'), // 路径重写
changeOrigin: true, // 是否有跨域
ws: true // websocket 是否有跨域
}
}
},
})
}
我们发起请求的时候,是以我们Vue项目的开发服务器的地址作为根地址的,也就是长这样:http://localhost:8080/api/getList,当我们开启了代理服务器后,就会根据你请求路径中是否包含'/api',然后决定是否进行转发请求,如果请求路径中的前缀为'/api',那么代理服务器就会进行转发,将/api以及后面的截取,拼接到target接口的请求跟地址后面,就像这样:http://192.168.13.11:9999/api/getList,如果做了路径重写,比如上面的将以/api开头的全部换成以/sys开头,然后再拼接到target接口的请求根地址后面进行请求转发。
注意点
Proxy代理,只在开发模式下(development)生效,部署到线上以后是无效的。
上线之后项目可能放在Nginx或Tomcat之类的,需要通过这些服务器去代理转发请求。
如果开发环境下连接线上的接口地址,线上的请求是通过Nginx进行代理转发的,线上和线下的URL前缀,就遇到URL中有这个前缀代理转发的这个前缀。如果线上和项目中的一致那么会导致响应回来的是一个index.html页面。