跨域資源共享(Cross-Origin Resource Sharing)實現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
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.在客服端寫下面代碼
"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#" %>
protected void Page_Load(object sender, EventArgs e)
{
Response.AddHeader("Access-Control-Allow-Origin", "http://www.yoursite.com:8080");
Response.Write("Yoyiorlee向各位朋友發來賀電:你的第一個跨域測試成功啦!!!");
}
</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';
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 = 'yoyiorlee.com';
補充:同源策略:
| URL | 說明 | 是否允許通信 |
| http://www.yoyiorlee.com/lab/a.html http://www.yoyiorlee.com/script/b.html |
同一域名下不同文件夾 | 允許 |
| http://www.yoyiorlee.com/a.html http://www.yoyiorlee.com/b.html |
同一域名下 | 允許 |
| http://www.yoyiorlee.com:8000/a.html http://www.yoyiorlee.com/b.html |
同一域名,不同端口 | 不允許 |
| http://www.yoyiorlee.com/a.html https://www.yoyiorlee.com/b.html |
同一域名,不同協議 | 不允許 |
| http://www.yoyiorlee.com/a.html http://70.32.92.74/b.html |
域名和域名對應ip | 不允許 |
| http://www.yoyiorlee.com/a.html http://blogs.yoyiorlee.com/b.html |
主域相同,子域不同 | 不允許 |
| http://www.cnblogs.com/a.html http://www.yoyiorlee.com/b.html |
不同域名 | 不允許 |
浙公網安備 33010602011771號