在js中,如何解决跨域问题是一个非常重要的内容。跨域问题cors:cross origin resource share。
同源策略:只有当协议、端口、域名都相同的页面,则两个页面具有相同的源。只要网站的协议protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用,会受到同源策略的限制。
注意:不管哪种跨域都需要服务器端的配合,服务器端才是跨域的主导。
1.天生跨域的标签:
在js中,有一些可以天生跨域的标签,例如图片img或者脚本script。
拥有src中的标签天生就可以跨域。
缺点:只能发送Get请求 ,无法访问服务器的响应文本(只是单向请求)。
2.利用postMessage进行跨域(跨页面消息传递):
// 父 目标.contentWindow.postMessage()
window.addEventListener('message', function(e) { alert(e.data); });
document.querySelector('iframe').contentWindow.postMessage('myMessage', '/'); // '/'表示同域 '*'所有
// 子 找父窗口:window.top || window.parentWindow
window.addEventListener('message', function(e) { alert(e.data); }); // 在监听事件内找父窗口 e.source
window.parentWindow.postMessage();
3.JSONP跨域:
第一步:想好跨域拿到数据后干什么,写好回调函数。
第二步:利用script标签天生能够跨域的特点去请求服务器,拿到一段javascript代码,回来执行!这段代码就是调用callback回调函数的代码。
第三步:服务器进行配合,返回一段js代码。
<script>
function callback(data) {
console.log('拿到的数据:' + data);
}
</script>
<script src="http://localhost:8888?key=callback"></script>
// 服务器
res.end(`${ funcName }(${ JSON.stringify(data) })`);
4.CORS跨域:
$.ajax({
url: 'http://localhost:8888',
success: function(data) {
console.log(data);
}
});
// 服务器
res.setHeader('Access-Control-Allow-Origin', '*'); // 允许所有请求跨域
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,DELETE') // 允许请求的类型
res.setHeader('Access-Control-Allow-Headers', 'X-PINGOTHER, Content-Type') // 预检请求
res.setHeader('Access-Control-Max-Age', '1000') // 请求最大响应时间
res.setHeader("Access-Control-Allow-Credentials", 'true') // 是否携带cookie
// ajax设置
"withCredentials": true
5.window.name + iframe:
利用的特点:iframe 标签的跨域能力;window.name 属性值在文档刷新后依旧存在的能力(且最大允许2M左右)。
document.querySelector('iframe').contentWindow.name = '张三';
6.修改document.domain跨子域:
前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用 document.domain 进行跨域,所以只能跨子域。
现在存在两个域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的页面,由于其 document.name不一致,无法在aaa下操作bbb的js。可以在aaa和bbb下通过js将 document.name = 'xxx.com'; 设置一致,来达到互相访问的作用。
7.WebSocket:
它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很棒的实现。
缺点:WebSocket 对象不支持 DOM 2 级事件侦听器,必须使用 DOM 0 级语法分别定义各个事件。
8.代理:
同源策略是针对浏览器端进行的限制,可以通过服务器端来解决该问题 DomainA客户端(浏览器) => DomainA服务器 => DomainB服务器 => DomainA客户端(浏览器)。
例如:react项目使用代理,就可以在package.json节点中配置"proxy"属性。
以上就是网上的一些大牛常常用的方法,不过现在大多使用天生跨域标签,CORS跨域和配置代理三种方法。