什么是跨域
由于浏览器同源政策。当前页面发起的请求的路径中,只要协议,域名,或者端口其中之一与本页面的路径不相同,就是跨域。
跨域方法
JSONP
先说说大家最熟悉的跨域解决方法JSONP。JSONP实际上使用了浏览器不会限制script和img跨域的特性。代码如下:
缺点:
- 安全问题,JSONP导致其他非公司网站也能使用这个请求。
- 无法发送POST请求。(这也是我之前某个项目里放弃JSONP的原因)。
CORS 跨域资源共享
CORS需要服务端和客户端相互配合,客户端请求和普通的ajax请求一样。
客户端请求分为2种,一种简单请求,另外一种预先请求。
缺点:
- 兼容问题,IE下有些不兼容。
- 需要后端配合,不利于前后端独立。
简单请求
请求方法是下列之一:GET,POST,HEAD
请求头是下列之一:application/x-www-form-urlencoded,multipart/form-data,text/plain。
上面这几种请求属于简单请求,当跨域时,浏览器会自动在头部中添加Origin。
服务器端接受到请求后,通过自身需求处理,返回带有Access-Control-Allow-Origin和
Access-Control-Allow-Methods的响应头。
预先请求
当请求条件超出简单请求的条件时,为预先请求。预先请求会发起2个请求。预先请求不会直接发起
对应的数据请求,而是首先发起OPTION请求,询问服务器是否允许当前域名页面发起跨域请求,跨域
方法是什么等。最后,得到浏览器认可后,才发起数据请求。
OPTIONS请求:
response:
数据请求:
response:
cookie,HTTP认证信息
CORS通常是不携带cookie请求和HTTP认证信息。如果需要携带,需要设置withCredentials属性为true。
服务端设置Access-Control-Allow-Credentials属性为true。当携带cookie时,Access-Control-Allow-Origin
不能为星号。
document.domain + iframe
通过在页面中嵌入iframe的方式。
父页面
子页面
缺点:
- 只支持主域名相同的页面。
- 子页面还得设置domain,很多场景确实都不适合。
postMessage
postMessage是一个HTML5的新api,提供了允许不同源的脚本之间相互通讯。
postMessage(data,origin)参数
data:传递的数据,HTML5中规定数据为任意类型。但是为了支持各种浏览器,数据最好为字符串。
origin:字符串参数,目标窗口的源,协议+主机+端口号。也可以设置为星号。
父页面
子页面
兼容IE XDomainRequest
IE8,IE9提供了XDomainRequest来解决跨域问题。
缺点:
- 只支持POST,GET请求。
- 协议不同的跨域无法支持。
- 无法携带cookie等。