Ajax跨域問題

龍恩0707發表於2013-08-29

      JavaScript 是一種在Web開發中經常使用的前端動態指令碼技術。在JavaScript中,有一個很重要的安全性限制,被稱為“Same-Origin Policy”(同源策略)。這一策略對於JavaScript程式碼能夠訪問的頁面內容做了很重要的限制,即JavaScript只能訪問與包含它的文件 在同一域下的內容。

    JavaScript 這個安全策略在進行多iframe或多視窗程式設計、以及Ajax程式設計時顯得尤為重要。根據這個策略,在hitao.com下的頁面中包含的 JavaScript程式碼,不能訪問在taobao.com域名下的頁面內容;甚至不同的子域名之間的頁面也不能通過JavaScript程式碼互相訪問。 對於Ajax的影響在於,通過XMLHttpRequest實現的Ajax請求,不能向不同的域提交請求,例如,在abc.example.com下的頁面,不能向def.example.com提交Ajax請求,等等。

 

下面我們分兩種情況討論跨域技術:首先討論不同子域的跨域技術,然後討論完全不同域的跨域技術
一: 不同的子域跨域技術。

 

   首先為了在本地電腦做demo 我們只需要在host分別繫結如下:127.0.0.1 abc.example.com 127.0.0.1 def.example.com 即可 然後假如在def.example.com域下有這麼一個頁面iframe1.html,JS程式碼為如下一個函式function test(){
            console.log(1);
        };

頁面我想巢狀abc.example.com域下一個iframe  <iframe src="http://abc.example.com/iframe/iframe2.html"></iframe> 然後再iframe2.html頁面通過    console.log(window.top.test());這麼一句程式碼去呼叫def.example.com域下iframe1.html的test函式。

 

  好,我們注意到,這個呼叫是被前面講到的“同源策略”所禁止的,JavaScript引擎會直接丟擲一個異常。

 

 

  為了實現上述呼叫,我們可以通過修改兩個頁面的domain屬性的方法做到。例如,我們可以將上面在abc.example.com和def.example.com下的兩個頁面的頂端都加上如下的JavaScript程式碼片段:

  document.domain = 'example.com';

 這樣,兩個頁面就變為同域了,前面的呼叫也可以正常執行了。

 這 裡需要注意的一點是,一個頁面的document.domain屬性只能設定成一個更頂級的域名(除了一級域名),但不能設定成比當前域名更深層的子域 名。例如,abc.example.com的頁面只能

將它的domain設定成example.com,不能設定成 sub.abc.example.com,當然也不能設定成一級域名com。

 上面的例子討論的是兩個頁面屬於iframe巢狀關係的情況,當兩個頁面是開啟與被開啟的關係時,原理也完全一樣。

 二:完全不同域的跨域技術:
1.通過JSONP實現跨域

 

     利用在頁面中建立<script>節點的方法向不同域提交HTTP請求的方法稱為JSONP,這項技術可以解決跨域提交Ajax請求的問題。JSONP的工作原理如下所述:

   假設在http://example1.com/index.php這個頁面中向http://example2.com/getinfo.php提交 GET請求,我們可以將下面的JavaScript程式碼放在http://example1.com/index.php這個頁面中來實現:

var eleScript= document.createElement("script");
    eleScript.type = "text/javascript";
    eleScript.src = "http://example2.com/getinfo.php";
    document.getElementsByTagName("HEAD")[0].appendChild(eleScript);

       當GET請求從http://example2.com/getinfo.php返回時,可以返回一段JavaScript程式碼,這段程式碼會自動執行,可以用來負責呼叫http://example1.com/index.php頁面中的一個callback函式。

   JSONP的優點是:它不像XMLHttpRequest物件實現的Ajax請求那樣受到同源策略的限制;它的相容性更好,在更加古老的瀏覽器中都可以 執行,不需要XMLHttpRequest或ActiveX的支援;並且在請求完畢後可以通過呼叫callback的方式回傳結果。

  JSONP的缺點則是:它只支援GET請求而不支援POST等其它型別的HTTP請求;它只支援跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript呼叫的問題。

 

 2. 通過iframe + form表單可以實現“post方式非同步跨域”。

 

     思路: 1.通過動態建立iframe 和 動態建立 form表單 iframe的name的值與form表單target相同就可以實現非同步跨域。把要傳遞的資料放在隱藏input裡面。

     程式碼如下:

<div class="aa">aaaa</div>
    <script>
        $('.aa').click(function(){
            crossDomainPost();
        });
        function crossDomainPost() {
          // Add the iframe with a unique name
          var iframe = document.createElement("iframe");
          var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
          document.body.appendChild(iframe);
          iframe.style.display = "none";
          iframe.contentWindow.name = uniqueString;

          // construct a form with hidden inputs, targeting the iframe
          var form = document.createElement("form");
          form.target = uniqueString;
          form.action = "http://def.example.com/iframe/iframe2.html";
          form.method = "POST";

          // repeat for each parameter
          var input = document.createElement("input");
          input.type = "hidden";
          input.name = "test";
          input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
          form.appendChild(input);

          document.body.appendChild(form);
          form.submit();
        }
        
    </script>

   思想來源  http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript 

 

 

 

相關文章