前言:像CORS對于現代前端這麼重要的技術在國内基本上居然很少有人使用和提及,在百度或者Google上搜尋CORS,搜到的中文文章基本都是另外一種衛星定位技術CORS的介紹,讓我等前端同學情何以堪(對比起來,用Google搜到的國外文章,基本都是跨域資源共享的介紹,說明了前端技術在國内外環境和發展的巨大差距)。
由此我将引入和介紹CORS,希望對大家有所幫助。
定義
簡言之,CORS就是為了讓AJAX可以實作可控的跨域通路而生的。
以往的解決方案
以前要實作跨域通路,可以通過JSONP、Flash或者伺服器中轉的方式來實作,但是現在我們有了CORS。
CORS與JSONP相比,無疑更為先進、友善和可靠。
1、 JSONP隻能實作GET請求,而CORS支援所有類型的HTTP請求。
2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得資料,比起JSONP有更好的錯誤處理。
3、 JSONP主要被老的浏覽器支援,它們往往不支援CORS,而絕大多數現代浏覽器都已經支援了CORS(這部分會在後文浏覽器支援部分介紹)。
詳細内容
要使用CORS,我們需要了解前端和伺服器端的使用方法。
1、 前端
以前我們使用Ajax,代碼類似于如下的方式:
var xhr = new XMLHttpRequest();
xhr.open("GET", "/hfahe", true);
xhr.send();
這裡的“/hfahe”是本域的相對路徑。
如果我們要使用CORS,相關Ajax代碼可能如下所示:
xhr.open("GET", "http://blog.csdn.net/hfahe", true);
請注意,代碼與之前的差別就在于相對路徑換成了其他域的絕對路徑,也就是你要跨域通路的接口位址。
我們還必須提供浏覽器回退功能檢測和支援,避免浏覽器不支援的情況。
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// 此時即支援CORS的情況
// 檢查XMLHttpRequest對象是否有“withCredentials”屬性
// “withCredentials”僅存在于XMLHTTPRequest2對象裡
xhr.open(method, url, true);
} else if (typeof!= "undefined") {
// 否則檢查是否支援XDomainRequest,IE8和IE9支援
// XDomainRequest僅存在于IE中,是IE用于支援CORS請求的方式
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// 否則,浏覽器不支援CORS
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
現在如果直接使用上面的腳本進行請求,會看到浏覽器裡控制台的報錯如下:
錯誤顯示的很明顯,這是因為我們還未設定Access-Control-Allow-Origin頭。
2、 伺服器
伺服器端對于CORS的支援,主要就是通過設定Access-Control-Allow-Origin來進行的。如果浏覽器檢測到相應的設定,就可以允許Ajax進行跨域的通路。
Apache:Apache需要使用mod_headers子產品來激活HTTP頭的設定,它預設是激活的。你隻需要在Apache配置檔案的<Directory>, <Location>, <Files>或<VirtualHost>的配置裡加入以下内容即可:
Header set Access-Control-Allow-Origin *
PHP:隻需要使用如下的代碼設定即可。
<?php
header("Access-Control-Allow-Origin:*");
以上的配置的含義是允許任何域發起的請求都可以擷取目前伺服器的資料。當然,這樣有很大的危險性,惡意站點可能通過XSS攻擊我們的伺服器。是以我們應該盡量有針對性的對限制安全的來源,例如下面的設定使得隻有http://blog.csdn.net這個域才能跨域通路伺服器的API。
Access-Control-Allow-Origin: http://blog.csdn.net
浏覽器支援情況
上文曾經提到,IE8和IE9在某種程度上可以通過XDomainRequest來提供同樣功能的支援。
使用案例
目前國外支援CORS的平台有很多,例如:
未來
從所有的浏覽器都支援來看,CORS将成為未來跨域通路的标準解決方案。無論是自己伺服器間的跨域通路,還是開放平台為第三方提供API,都将采用這種統一的解決方案,因為它簡單、高效,受到所有主流浏覽器的支援。它非常重要,也會讓我們的網絡變得更加開放。
參考文章
<a href="http://www.vancl.com/?source=kbh1983&sourcesuninfo=ad-3090-1-52-0-1" target="_blank"></a>