跨域常看法决方案

  因为考虑到安全性问题,HTML的同源策略不容许JavaScript进行跨域操做,可是随着web端功能愈来愈多,对跨域需求逐渐增大,因而乎便催生了不少解决跨域的方法,经过网络搜索和资料查询,主要比较常见的解决方案有如下几种:

    1、设置 document.domain

  •    原理:相同主域名下不一样子域页面,经过设置document.domain让他们同域;
  •    限制:此方法只适用与跨子域的,对于跨父域名,仍然不可行,且须要载入iframe页面。
 1 // url http://bentos.com/foo
 2 var ifr = document.createElement('iframe');
 3 ifr.src = 'http://b.bentos.com/foo'; 
 4 ifr.onload = function(){
 5     var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
 6     ifrdoc.getElementsById("foo").innerHTML);
 7                         };
 8 
 9 ifr.style.display = 'none';
10 document.body.appendChild(ifr);

 上述代码所在的URL是http://bentos.com/foo,它对http://b.bentos.com/bar的DOM访问要求后者将 document.domain往上设置一级html

 // URL http://b.bentos.com/bar
1 document.domain = 'bentos.com'

// URL: http://b.bentos.com/foo var data = { foo: 'bar', bar: 'foo' }; callback(data);



2、jsonp

  • 原理:<script>是能够跨域的,并且在跨域脚本中能够直接回调当前脚本的函数。
  • 限制:须要建立一个DOM对象而且添加到DOM树,只能用于GET方法
  • 1 // URL: http://b.bentos.com/foo
    2 var data = {
    3     foo: 'bar',
    4     bar: 'foo'
    5                   };
    6 callback(data);
  • 1 // URL: http://bentos.com/foo
    2 var callback = function(data){
    3     // 处理跨域请求获得的数据
    4                              };
    5 var script = $('<script>', {src: 'http://b.bentos.com/bar'});
    6 $('body').append(script);
     
      

 


3、navigation 对象

  • 原理:iframe之间是共享navigator对象的,用它来传递信息
  • 要求:IE6/7

    有些人注意到了IE6/7的一个漏洞:iframe之间的window.navigator对象是共享的。 咱们能够把它做为一个Messenger,经过它来传递信息。好比一个简单的委托:web

 

1 // bentos.com
2 navigation.onData(){
3     // 数据到达的处理函数
4 }
5 typeof navigation.getData === 'function' 
6     || navigation.getData()
// baidu.com
navigation.getData = function(){
    $.get('/path/under/baidu.com')
        .success(function(data){
            typeof navigation.onData === 'function'
                || navigation.onData(data)
        });
}

   document.navigator相似,window.name也是当前窗口全部页面所共享的。也能够用它来传递信息。json

4、window.postMessage

 

  • 原理:HTML5容许窗口之间发送消息
  • 限制:浏览器须要支持HTML5,获取窗口句柄后才能相互通讯

 

    这是一个安全的跨域通讯方法,postMessage(message,targetOrigin)也是HTML5引入的特性。 能够给任何一个window发送消息,不管是否同源。第二个参数能够是*但若是你设置了一个URL但不  相符,那么该事件不会被分发。看一个普通的使用方式吧:跨域

 

 1 // URL: http://bentos.com/foo
 2 var win = window.open('http://b.com/bar');
 3 win.postMessage('Hello, bar!', 'http://b.com'); 
 4 
 5 
 6 
 7 // URL: http://baidu.com/bar
 8 window.addEventListener('message',function(event) {
 9     console.log(event.data);
10 });

 

 注意IE8及小于IE8的版本不支持addEventListener,须要使用attachEvent来监听事件。 参见:事件处理中的this:attachEvent, addEventListener, onclick浏览器

5、跨域资源共享(CORS)

  • 原理:服务器设置Access-Control-Allow-OriginHTTP响应头以后,浏览器将会容许跨域请求
  • 限制:浏览器须要支持HTML5,能够支持POST,PUT等方法

   例如,从http://a.com要访问http://b.com的数据,一般状况下Chrome会因跨域请求而报错:安全

1 XMLHttpRequest cannot load http://b.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.com' is therefore not allowed access.

 

   错误缘由是被请求资源没有设置Access-Control-Allow-Origin,因此咱们在b.com的服务器中设置这个响应头字段便可:服务器

1 Access-Control-Allow-Origin: *              # 容许全部域名访问,或者
2 Access-Control-Allow-Origin: http://a.com   # 只容许全部域名访问

 

 

     在Html5出来以前,跨域采用常见方法为jsonp,jQuery也给出了支持。 值得注意的是它只是Hack,并无产生额外的安全问题。 由于JSONP要成功获取数据,须要跨域资源所在服务器的配合,好比资源所在服务器须要自愿地回调一个合适的函数,因此服务器仍然有能力控制资源的跨域访问。网络

     跨域的正道仍是要使用HTML5提供的CORS头字段以及window.postMessage, 能够支持POST, PUT等HTTP方法,从机制上解决跨域问题。 值得注意的是Access-Control-Allow-Origin头字段是资源所在服务器设置的, 访问控制的责任仍然是在提供资源的服务器一方,这和JSONP是同样的道理。app

相关文章
相关标签/搜索