为什么会有跨域问题
- 是因为浏览器的同源策略限制了,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>
四、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,原因是同源策略导致
六、反向代理
七、websocket
八、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,发送窗口的实例
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。