关于前端:跨域解决方案

为什么会有跨域问题

  • 是因为浏览器的同源策略限度了,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,发送窗口的实例

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理