共计 2323 个字符,预计需要花费 6 分钟才能阅读完成。
为什么会有跨域问题
- 是因为浏览器的同源策略限度了,A 域名下的网址,无奈获取 B 域名下的资源,这里的资源指:
- DOM 及 JS 对象,脚本发动的 ajax 申请,以及 cookie 和 sessionstorage/localstorage
- 跨域指域名、端口、协定三者中有一个不一样
绕过跨域
一、jsonp
- 通过某些标签的 src 属性,能够不受跨域限度获取到不同域的资源的,如 script
- 采纳 jsonp 须要服务器的配合,原理上是通过服务器返回 js 脚本调用本地 js 办法,并在拼接脚本的过程中将所需数据填充进返
<!-- A 域名下网页 -->
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 调用不同域的接口并传数据
script.src = 'http://otherDomain.com?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {alert(JSON.stringify(res));
}
</script>
// B 域名下服务器返回
handleCallback({"status": true, "user": "admin"})
- 服务器返回脚本 handleCallback({“status”: true, “user”: “admin”}),在 script 下会主动执行,即调用了 A 网页的办法,并回传了参数,最终成果就是 A 域名下网页获取了 B 域名下服务器的数据
二、document.domain 及 iframe
- 仅实用于主域雷同,而子域不同,如
- a.domain.com 以及 b.domain.com
- 若 a.domain.com 与 b.domain2.com 则不实用
- 通过强制设置 a、b 页面的 document.domain 为同一个主域,domain.com 即可互相拜访
- 即 document.domain = domain.com
三、两头页 iframe
- 若主域名也不一样,如 www.domain.com 与 www.domain2.com
- 能够新建一个 c 页面,c 页面与 a 页面域名雷同,如 www.domain.com/c.html
- 将 c 页面作为 iframe 嵌入 b 页面
- 在加载过程中,通过 url 传参给 c 页面管制其调用 a 页面办法
<!-- www.domain.com/a.html -->
<iframe id="iframe" src="http://www.domain2.com/b.html" />
<script>
function handleCallback(res) {alert(res);
}
</script>
<!-- www.domain2.com/b.html -->
<iframe id="iframe" src="http://www.domain.com/c.html" />
<script>
var iframe = document.getElementById('iframe');
iframe.src = iframe.src + '#b';
</script>
<!-- www.domain.com/c.html -->
<script>
// 监听 b.html 传来的 hash 值
window.onhashchange = function () {
// 再通过操作同域 a.html 的 js 回调,将后果传回
window.parent.parent.handleCallback('hello:' + location.hash);
};
</script>
- 最初 alert(hello:#b)
四、window.name
- window.name 在不同页面跳转时会始终存在,无论是否同域都能够拜访
- 在 www.domain.com/a.html 下设置了 window.name,在 www.domain.com/b.html 能够读取进去
- 则不同域资源能够通过放到 window.name 中传递,这和通过 url 传递相似,window.name 反对保留大略 2mb 左右的数据,保留的数据会 string 化
五、CORS
- 须要服务器配合,设置响应头 Access-Control-Allow-Origin
- 若须要携带 cookie 申请,服务端减少响应头 Access-Control-Allow-Credentials,客户端发送办法须要设置,以原生为例:xhr.withCredentials = true
- 若抉择携带 cookie,则 Access-Control-Allow-Origin 不能设置为 *,必须明确指定域名
- 同时携带的 cookie 时服务端域名下的 cookie,起因是同源策略导致
六、反向代理
- 如 nginx,反向代理调试
七、websocket
- 不同于 http,全双工通信,不受同源策略限度
八、postMessage
- otherWindow:要接管信息的 window 实例
- message:要传递的信息
- targetOrigin:指标域
- transfer:没太懂,有些浏览器如同也没实现这个字段,临时忽视
// A 域名
otherWindow.postMessage(message, targetOrigin, [transfer]);
// B 域名
window.addEventListener('message', function(e) {alert('data from otherDomain:' + e.data);
}, false);
- 通过监听 message 事件获取数据
- message 事件有以下属性
- data,传过来的对象
- origin,发送方的域名
- source,发送窗口的实例
正文完