前端跨域汇总
什么是跨域
要搞懂什么是跨域要明白同源策略,同源策略满足条件有三个:
1.协议相同
2.端口相同
3.域名相同
同源策略有什么限制?
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
url中任意一个部分不相同都会造成跨域问题,但是也有例外,script标签的src和link标签的href及iframe的src是不受同源策略的限制。这个便可以成为我们解决跨域问题的桥梁。
jsonp跨域
jsonp原理就是利用了script标签的src属性不受同源策略的影响。但是他有一个致命的缺点,jsonp的跨域只支持get请求。
原生的实现
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://www.crossDomain.com:8080/login?user=admin&callback=callback';
document.head.appendChild(script);
// 回调执行函数
function callback(res) {
alert(JSON.stringify(res));
}
服务器端返回
callback({"status": true, "user": "admin"})
cors跨域
cors跨域主要是在服务端进行的
服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。
注意:如果需要带cookie ,Access-Control-Allow-Origin不能设置为(允许所有域),必须设置为具体的地址,例如 Access-Control-Allow-Origin:http://www.crossDomain.com:8080*
前端代码:
var xhr = new XMLHttpRequest();
// 前端设置是否带cookie,true为携带
xhr.withCredentials = true;
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');//设置
xhr.send('user=admin');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}};
服务器端设置
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");
// 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
response.setHeader("Access-Control-Allow-Credentials", "true");
// 提示OPTIONS预检时,后端需要设置的两个常用自定义头
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
cors跨域的原理是基于option请求的,option请求的两个作用
1、获取服务器支持的HTTP请求方法;
2、用来检查服务器的性能。
进行跨域请求的时候,客户端首先发送服务器一个预检请求,预检请求是一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。客户端获取到option中返回的服务器信息,获取到当前的服务器设置的允许的域,客户端再次带着跨域的信息和真正的请求向服务器发送请求,服务器相应并带回跨域信息,浏览器端认证返回信息中跨域信息允许,则成功跨域。如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。但是状态吗有可能还是200。其实这时候是进行了正确的请求只是浏览器端不认识,所以才造成了跨域。
postMessage跨域
postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递
postMessage(data,origin)方法接受两个参数
origin: 协议+主机+端口号 为要跨的域。
data:为要发送的数据。
eg: window.parent.postMessage(JSON.stringify(data), ‘http://www.crossdDmain.com’);
还有其他几个,但是我个人觉得用的都比较少。所以就不记录了
补充一张图