- 什么是跨域?
跨域是指跨域名的访问
比如两个地址,A地址向B地址发送ajax请求,但是A地址和B地址里面:
协议 域名 端口 不全相同,则请求是跨域的
- 跨域违反了同源策略
同源是指 协议-域名-端口 三者都相同
不同源之间的页面不允许相互访问数据,在浏览器规定中如果js运行在源A里面,则只能获取A的数据,不能获取B的数据,不允许跨域,这样做的好处就是保护了浏览器里面的安全
- 跨域是客户端问题还是服务器问题?
跨域是客户端浏览器问题
- 跨域的过程
浏览器向服务器发送请求,服务器接收到,响应数据给浏览器,但是浏览器经过同源策略检
查协议、域名、端口
检查这三个只要发现任何一个不一样就抛出异常
- 解决跨域问题的最佳方法
将前端的项目部署到和接口同源的服务器上面
但是在开发阶段不允许,需要和后台协商,操作起来也很麻烦
- 常用的解决跨域的方法
- 前端:
Jsonp
最早的解决方案,利用script标签可以跨域的原理实现。
限制:
需要服务的支持
只能发起GET请求
- 后端:
CORS
后端写代码(CORS)在响应中添加必要的响应头,让响应回来之后浏览器不报错
规范化的跨域请求解决方案,安全可靠。
优势:
在服务端进行控制是否允许跨域,可自定义规则
支持各种请求方式
缺点:
会产生额外的请求
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
浏览器端:
目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。
服务端:
CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。只不过,浏览器会在请求中携带一些头信息,我们需要以此判断是否运行其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。
- 使用代理配置解决跨域问题
在前端服务和后端接口服务之间 架设一个中间代理服务,它的**地址保持和前端服务一致,那么:
1. 代理服务和前端服务之间由于协议域名端口三者统一不存在跨域问题,可以直接发送请求
2. 代理服务和后端服务之间由于并不经过浏览器没有同源策略的限制,可以直接发送请求
这样,我们就可以通过中间这台服务器做接口转发,在开发环境下解决跨域问题,看起来好像挺复杂,其实vue-cli已经为我们内置了该技术,我们只需要按照要求配置一下即可。
- window.name + iframe跨域
window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。
总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
- postMessage跨域
postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递
用法:postMessage(data,origin)方法接受两个参数
data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。