跨域本质是浏览器基于同源策略的一种安全手段。
一定要注意跨域是浏览器的限制,你用抓包工具抓取接口数据,是可以看到接口已经把数据返回回来了,只是浏览器的限制,你获取不到数据。用postman请求接口能够请求到数据。这些再次印证了跨域是浏览器的限制。
一、什么是同源策略?
一个url由三部分组成:协议,域名(ip地址),端口。
所谓同源(即指在同一个域)具有以下三个相同点:
- 协议相同(protocol)
- 主机相同(host)
- 端口相同(port)
反之非同源请求,也就是协议、端口、主机其中一项不相同的时候,这时候就会产生跨域。
例子如下:
发送请求地址:http:47.96.127.5:8080/index 接受请求地址:http:47.96.127.5:8083/index //不同源 端口不同
发送请求地址:http:47.96.127.5:8080/index 接受请求地址:http:47.96.127.6:8080/index //不同源 ip不同
发送请求地址:http:47.96.127.5:8080/index 接受请求地址:https:47.96.127.5:8080/index //不同源 协议不同
发送请求地址:http:47.96.127.5:8080/index 接受请求地址:http:47.96.127.5:8080/login //同源 协议,端口,ip都相同,路径不同无所谓
而当我们的请求不符合同源策略的时候,往往会出现下面的报错:
二、解决跨域问题的办法:
2.1 通过jsonp解决跨域
通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
Vue实现:
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'handleCallback'
}).then((res) => {
console.log(res);
})
优点: jsonp优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题 。
缺点:仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
2.2 前端代理解决跨域
每一个框架的代理配置都不一样,这里仅以vue进行举例:
vue框架会有 vue.config.ts / vue.config.js 文件,文件中会有proxy字段、字段按图中配置方法。即可完成跨域
proxy: {
"/api": {
target: "https://heimahr.itheima.net",
},
},
2.3 服务端代理(Nginx代理)
nginx代理一般使用在生产环境。是服务端解决跨域的一种方案。
简单配置模板:
#如果监听到请求接口地址是 www.xxx.com/api/page ,nginx就向http://www.yyy.com:9999/api/page这个地址发送请求
server {
listen 80;
server_name www.xxx.com;
#判过滤出含有api的请求
location /api/ {
proxy_pass http://www.yyy.com:9999; #真实服务器的地址
}
}