DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> AJAX入門 >> AJAX詳解 >> 跨域資源共享(Cross-Origin Resource Sharing)實現Ajax跨域請求
跨域資源共享(Cross-Origin Resource Sharing)實現Ajax跨域請求
編輯:AJAX詳解     

最近正在做的幾個項目都用到了Ajax跨域請求,由於處於安全的角度,Firefox、Chrome等很多浏覽器(IE除開)都不允許跨域請求或調用,折騰好久,終於解決了AJax跨域請求這個蛋疼的問題,在網上也找了很久的資料,嘗試N次都失敗,今天在無意之中看到一篇跨域資源共享的文章,這讓我輕松的解決了跨域問題,不多說。

跨域請求,就是一個站點中的資源去訪問另外一個不同域名站點上的資源。這種情況很常見,比如說通過 <link> 標簽加載外部樣式表文件、通過 <img> 標簽加載外部圖片、通過 <script> 標簽加載外部腳本文件等等。默認情況下,腳本訪問文檔屬性等數據采用的是同源策略(Same origin policy)

如果兩個頁面的協議、域名和端口是完全相同的,那麼它們就是同源的。 如果兩個頁面的主域名相同,則還可以通過設置 document.domain 屬性將它們認為是同源的。

隨著 Web2.0 和 社交網絡 的興起,Web 應用對跨域訪問的需求也越來越多,但是在腳本中進行跨域請求是受安全性限制的。比如分布式應用,主網站和二級域名網站的通信等等。

許多人還沒意識到當前幾乎所有的浏覽器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome)都可通過名為跨域資源共享(Cross-Origin Resource Sharing)的協議支持AJax跨域調用。 對一個簡單的請求,沒有自定義頭部,要麼使用GET,要麼使用POST,它的主體是text/plain,請求用一個名叫Orgin的額外的頭部發送。Origin頭部包含請求頁面的頭部(協議,域名,端口),這樣服務器可以很容易的決定它是否應該提供響應。

在IE8中也是一樣,用同樣的方式你需要使用XDomainRequest object

 var xdr = new XDomainRequest();xdr.open("get", "http://www.msnova.Net/resource/");
xdr.onload = function(){
//do something
};
xdr.send(); 

 

方法一:跨域資源共享(Cross-Origin Resource Sharing)實現AJax跨域請求  (跨域資源共享,該規范地址:http://www.w3.org/TR/access-control/和http://dev.w3.org/2006/waf/Access-control/)

1.在客服端寫下面代碼

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHtml 1.0 Transitional//EN"  
 "http://www.w3.org/TR/xhtml1/DTD/xHtml1-transitional.dtd">  
<Html XMLns="http://www.w3.org/1999/xHtml">  
<head>  
  <title>AJax跨域請求測試</title>  
</head>  
<body>  
  <input type='button' value='開始測試' onclick='cross_domain_request()' />  
  <div id="content"></div>  
  <script type="text/Javascript"> 
    var xhr = new XMLHttpRequest();  
    var url = 'http://www.msnova.Net/resource/';  
    function cross_domain_request() {  
      document.getElementById("content").innerHtml = "開始……";  
      if (xhr) {  
        xhr.open('GET', url, true);  
        xhr.onreadystatechange = handler;  
        xhr.send();  
      } else {  
        document.getElementById("content").innerHtml = "不能創建 XMLHttpRequest";  
      }  
    }  
    function handler(evtXHR) {  
      if (xhr.readyState == 4) {  
        if (xhr.status == 200) {  
          var response = xhr.responseText;  
          document.getElementById("content").innerHtml = "結果:" + response;  
        } else {  
          document.getElementById("content").innerHtml = "不允許跨域請求。";  
        }  
      }  
      else {  
        document.getElementById("content").innerHtml += "<br/>執行狀態 readyState:" + xhr.readyState;  
      }  
    }  
</script>  
</body>  
</Html>

 

 

 

 

2.在服務端寫(可寫在前台頁面,也可在後台文件中寫)

 <%@ Page Language="C#" %>  

<script runat="server"> 
  protected void Page_Load(object sender, EventArgs e)  
  {  
    Response.AddHeader("Access-Control-Allow-Origin", "http://www.yoursite.com:8080");  
    Response.Write("孟憲會向各位朋友發來賀電:你的第一個跨域測試成功啦!!!");  
  }  
</script>

 

 

 注意:在請求信息中,浏覽器使用 Origin 這個 HTTP 頭來標識該請求來自於 http://www.yoursite.com:8080;在返回的響應信息中,使用 Access-Control-Allow-Origin 頭來控制哪些域名的腳本可以訪問該資源。如果設置 Access-Control-Allow-Origin:*,則允許所有域名的腳本訪問該資源。如果有多個,則只需要使用逗號分隔開即可。

 注意:在服務器端,Access-Control-Allow-Origin 響應頭 http://www.yoursite.com:8080 中的端口信息不能省略。

 如果想實現 XMLHttpRequest 來請求任意一個網站的數據,則需設置:

 Response.AddHeader("Access-Control-Allow-Origin", "http://www.yoursite.com:8080");

 這行代碼就告訴浏覽器,只有來自 http://www.yoursite.com:8080 源下的腳本才可以進行訪問。

 推薦閱讀:http://blog.csdn.Net/net_lover/archive/2010/01/11/5172509.ASPx

 這樣就可以實現跨域請求了,總結一下網上的方法,我絕不錯的

方法二:document.domain+iframe

 對於主域相同而子域不同的例子,可以通過設置document.domain的辦法來解決。具體的做法是可以在http://www.msnova.Net/a.Html和http:// blogs.msnova.Net/b.Html兩個文件中分別加上document.domain = ‘msnova.Net’;

然後通過a.Html文件中創建一個iframe,去控制iframe的contentDocument,這樣兩個JS文件之間就可以“交互”了。當然這種辦法只能解決主域相同而二級域名不同的情況

www.msnova.Net上的a.Html 

     document.domain = 'msnova.Net';

    var ifr = document.createElement('iframe');
    ifr.src = 'http://script.msnova.Net/b.Html';
    ifr.style.display = 'none';
    document.body.appendChild(ifr);
    ifr.onload = function(){
        var x = ifr.contentDocument;
        alert(x.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
    

 script.msnova.Net上的b.Html

document.domain = 'msnova.Net'; 

補充:同源策略:

URL 說明 是否允許通信 http://www.msnova.Net/lab/a.Html
http://www.msnova.Net/script/b.Html 同一域名下不同文件夾 允許 http://www.msnova.Net/a.Html
http://www.msnova.Net/b.Html 同一域名下 允許 http://www.msnova.Net:8000/a.Html
http://www.msnova.Net/b.Html 同一域名,不同端口 不允許 http://www.msnova.Net/a.Html
https://www.msnova.Net/b.Html 同一域名,不同協議 不允許 http://www.msnova.Net/a.Html
http://70.32.92.74/b.Html 域名和域名對應ip 不允許 http://www.msnova.Net/a.Html
http://blogs.msnova.Net/b.Html 主域相同,子域不同 不允許 http://www.cnblogs.com/a.Html
http://www.msnova.Net/b.Html 不同域名 不允許
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved