跨域问题及解决思路

形成跨域的两种策略

浏览器的同源策略会致使跨域,这里同源策略又分为如下两种javascript

  1. DOM同源策略:禁止对不一样源页面DOM进行操做。这里主要场景是iframe跨域的状况,不一样域名的iframe是限制互相访问的。
  2. XmlHttpRequest同源策略:禁止使用XHR对象向不一样源的服务器地址发起HTTP请求。
只要协议、域名、端口有任何一个不一样,都被看成是不一样的域,之间的请求就是跨域操做。

 

为何要有跨域限制

了解完跨域以后,想必你们都会有这么一个思考,为何要有跨域的限制,浏览器这么作是出于何种缘由呢。其实仔细想想就会明白,跨域限制主要是为了安全考虑。html

 

AJAX同源策略主要用来防止CSRF攻击。若是没有AJAX同源策略,至关危险,咱们发起的每一次HTTP请求都会带上请求地址对应的cookie,那么能够作以下攻击:java

  1. 用户登陆了本身的银行页面 http://mybank.comhttp://mybank.com向用户的cookie中添加用户标识。
  2. 用户浏览了恶意页面 http://evil.com。执行了页面中的恶意AJAX请求代码。
  3. http://evil.comhttp://mybank.com发起AJAX HTTP请求,请求会默认把http://mybank.com对应cookie也同时发送过去。
  4. 银行页面从发送的cookie中提取用户标识,验证用户无误,response中返回请求数据。此时数据就泄露了。
  5. 并且因为Ajax在后台执行,用户没法感知这一过程。

 

DOM同源策略也同样,若是iframe之间能够跨域访问,能够这样攻击:ajax

  1. 作一个假网站,里面用iframe嵌套一个银行网站 http://mybank.com
  2. 把iframe宽高啥的调整到页面所有,这样用户进来除了域名,别的部分和银行的网站没有任何差异。
  3. 这时若是用户输入帐号密码,咱们的主网站能够跨域访问到http://mybank.com的dom节点,就能够拿到用户的输入了,那么就完成了一次攻击。

因此说有了跨域跨域限制以后,咱们才能更安全的上网了。json

 

跨域的解决方式

> 跨域资源共享

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。 对于这个方式,阮一峰老师总结的文章特别好,但愿深刻了解的能够看一下http://www.ruanyifeng.com/blog/2016/04/cors.html后端

这里我就简单的说一说大致流程。api

  1. 对于客户端,咱们仍是正常使用xhr对象发送ajax请求。
    惟一须要注意的是,咱们须要设置咱们的xhr属性withCredentials为true,否则的话,cookie是带不过去的哦,设置: xhr.withCredentials = true;
  2. 对于服务器端,须要在 response header中设置以下两个字段:
    Access-Control-Allow-Origin: http://www.yourhost.com
    Access-Control-Allow-Credentials:true
    这样,咱们就能够跨域请求接口了。

> jsonp实现跨域

基本原理就是经过动态建立script标签,而后利用src属性进行跨域。跨域

这么说比较模糊,咱们来看个例子:浏览器

// 定义一个fun函数 function fun(fata) { console.log(data); }; // 建立一个脚本,而且告诉后端回调函数名叫fun var body = document.getElementsByTagName('body')[0]; var script = document.gerElement('script'); script.type = 'text/javasctipt'; script.src = 'demo.js?callback=fun'; body.appendChild(script); 

返回的js脚本,直接会执行。因此就执行了事先定义好的fun函数了,而且把数据传入了进来。安全

fun({"name": "name"}) 

固然,这个只是一个原理演示,实际状况下,咱们须要动态建立这个fun函数,而且在数据返回的时候销毁它。

由于在实际使用的时候,咱们用的各类ajax库,基本都包含了jsonp的封装,不过咱们仍是要知道一下原理,否则就不知道为何jsonp不能发post请求了~

> 服务器代理

浏览器有跨域限制,可是服务器不存在跨域问题,因此能够由服务器请求所要域的资源再返回给客户端。

 

服务器代理是万能的。

> document.domain来跨子域

对于主域名相同,而子域名不一样的状况,可使用document.domain来跨域 这种方式很是适用于iframe跨域的状况,直接看例子吧 好比a页面地址为 http://a.yourhost.com b页面为 http://b.yourhost.com。 这样就能够经过分别给两个页面设置 document.domain = http://yourhost.com 来实现跨域。 以后,就能够经过 parent 或者 window[‘iframename’]等方式去拿到iframe的window对象了。

 

使用window.name进行跨域

window.name跨域一样是受到同源策略限制,父框架和子框架的src必须指向统一域名。window.name的优点在于,name的值在不一样的页面(或者不一样的域名),加载后仍然存在,除非你显示的更改。而且支持的长度达到2M.

//a页面的代码 <script type="text/javascript"> iframe = document.createElement('iframe'); iframe.style.display = 'none'; var state = 0; iframe.onload = function() { if(state === 1) { var data = iframe.contentWindow.name; console.log(data); iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; iframe.contentWindow.location = 'http://m.zhuanzhuan.58.com:8887/b.html'; } }; document.body.appendChild(iframe); </script> 

 

//b页面代码 <script type="text/javascript"> window.name = "hello"; </script> 

 

> location.hash跨域

location.hash方式跨域,是子框架具备修改父框架src的hash值,经过这个属性进行传递数据,且更改hash值,页面不会刷新。可是传递的数据的字节数是有限的。

//a页面的代码 <script type="text/javascript"> iframe = document.createElement('iframe'); iframe.style.display = 'none'; var state = 0; iframe.onload = function() { if(state === 1) { var data = window.location.hash; console.log(data); iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; iframe.contentWindow.location = 'http://m.zhuanzhuan.58.com:8887/b.html'; } }; document.body.appendChild(iframe); </script> 

 

//b页面代码 <script type="text/javascript"> parent.location.hash = "world"; </script> 

 

> 使用postMessage实现页面之间通讯

信息传递除了客户端与服务器以前的传递,还存在如下几个问题:

  • 页面和新开的窗口的数据交互。
  • 多窗口之间的数据交互。
  • 页面与所嵌套的iframe之间的信息传递。

window.postMessage是一个HTML5的api,容许两个窗口之间进行跨域发送消息。这个应该就是之后解决dom跨域通用方法了,具体能够参照MDN。

补充: 其实还有一些方法,好比window.name和location.hash。就很适用于iframe的跨域,不过iframe用的比较少了,因此这些方法也就有点过期了。

这些就是我对跨域的了解了,实际状况下,通常用cors,jsonp等常见方法就能够了。不过遇到了一些很是规状况,咱们仍是须要知道有更多的方法能够选择的

相关文章
相关标签/搜索