跨域常看法決方案

  因爲考慮到安全性問題,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

相關文章
相關標籤/搜索