? ? ? 前言:像CORS對于現代前端這么重要的技術在國內基本上居然很少有人使用和提及,在百度或者Google上搜索CORS,搜到的中文文章基本都是另外一種衛星定位技術CORS的介紹,讓我等前端同學情何以堪(對比起來,用Google搜到的國外文章,基本都是跨域資源共享的介紹,說明了前端技術在國內外環境和發展的巨大差距)。
? ? ? 我之前《[用HTML5實現人臉識別](http://blog.csdn.net/hfahe/article/details/7485452)》這篇文章中提到了“Face.com實現了[**CORS**](http://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html)(跨域資源共享)。CORS系統基本上可以讓服務器暴露給其它域上文件的Ajax調用。這是一個偉大的功能,我希望更多的服務能夠使用它。”在這篇文章介紹的實現方式里,我們可以自由的使用自己本域的JS代碼通過Ajax來調用Face.com的API,這是一種很美妙的方式,而在以前我們很難做到這一點。
? ? ? 由此我將引入和介紹CORS,希望對大家有所幫助。
**定義**
? ? ??CORS其實出現時間不短了,它在[維基百科](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)上的定義是:**跨域資源共享(CORS**?)是一種網絡瀏覽器的技術規范,它為Web服務器定義了一種方式,允許網頁從不同的域訪問其資源。而這種訪問是被[同源策略](http://en.wikipedia.org/wiki/Same_origin_policy)所禁止的。CORS系統定義了一種瀏覽器和服務器交互的方式來確定是否允許跨域請求。?它是一個妥協,有更大的靈活性,但比起簡單地允許所有這些的要求來說更加安全。
? ? ??而W3C的[官方文檔](http://www.w3.org/TR/cors/)目前還是工作草案,但是正在朝著W3C推薦的方向前進。
? ? ??簡言之,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代碼可能如下所示:
~~~
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://blog.csdn.net/hfahe", true);
xhr.send();
~~~
? ? ??請注意,代碼與之前的區別就在于相對路徑換成了其他域的絕對路徑,也就是你要跨域訪問的接口地址。
? ? ??我們還必須提供瀏覽器回退功能檢測和支持,避免瀏覽器不支持的情況。
~~~
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進行跨域的訪問。
? ? ??HTTP 頭的設置方法有很多,[http://enable-cors.org/](http://enable-cors.org/)這篇文章里對各種服務器和語言的設置都有詳細的介紹,下面我們主要介紹Apache和PHP里的設置方法。
? ? ??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
~~~
**瀏覽器支持情況**
****
? ? ??上圖為各瀏覽器對于CORS的支持情況(綠色為支持,數據來源:[http://caniuse.com/cors](http://caniuse.com/cors)),看起來相當樂觀。主流瀏覽器都已基本提供對跨域資源共享的支持,所以,CORS才會在國外使用的如此普遍。
? ? ??上文曾經提到,IE8和IE9在某種程度上可以通過XDomainRequest來提供同樣功能的支持。
**使用案例**
? ? ??目前國外支持CORS的平臺有很多,例如:

? ? ??[Google APIClient Library for JS](http://code.google.com/p/google-api-javascript-client/wiki/CORS)
? ? ??[Google CloudStorage](https://developers.google.com/storage/docs/cross-origin)

? ? ??[Face.com API](http://developers.face.com/docs/api/)
**未來**
? ? ??從所有的瀏覽器都支持來看,CORS將成為未來跨域訪問的標準解決方案。無論是自己服務器間的跨域訪問,還是開放平臺為第三方提供API,都將采用這種統一的解決方案,因為它簡單、高效,受到所有主流瀏覽器的支持。它非常重要,也會讓我們的網絡變得更加開放。
**參考文章**
? ? ??[IE10中的CORS forXHR](http://www.iefans.net/ie10-cors-for-xhr/)
? ? ??[USING CORS](http://www.html5rocks.com/en/tutorials/cors/)
? ? ? 原創文章,轉載請注明:來自蔣宇捷的博客(http://blog.csdn.net/hfahe)
- 前言
- AutoPager的簡單實現
- 利用CSS3特性巧妙實現漂亮的DIV箭頭
- IE9在Win7下任務欄新特性簡介
- 瀏覽器九宮格的簡單實現
- Raphael js庫簡介
- 使用CSS3構建Ajax加載動畫
- 用CSS3創建動畫價格表
- 用CSS3實現瀏覽器的縮放功能
- 用純CSS3實現QQ LOGO
- 用CSS3創建旋轉載入器
- 使用Javascript開發移動應用程序
- 用HTML5創建超酷圖像灰度漸變效果
- 使用CSS3創建文字顏色漸變(CSS3 Text Gradient)
- 僅用CSS創建立體旋轉幻燈片
- 如何創建跨瀏覽器的HTML5表單
- 用CSS3實現動畫進度條
- HTML5 Guitar Tab Player
- 奇妙的HTML5 Canvas動畫實例
- 談HTML5和CSS3的國際化支持
- 實現跨瀏覽器的HTML5占位符
- 前端開發必備工具:WhatFont Bookmarklet-方便的查詢網頁上的字體
- 使用HTML5和CSS3來創建幻燈片
- HTML5之美
- 如何使用HTML5創建在線精美簡歷
- 以小見大、由淺入深-談如何面試Javascript工程師
- 快速入門:HTML5強大的Details元素
- 用CSS3實現圖像風格
- HTML5視頻字幕與WebVTT
- 用純CSS3實現Path華麗動畫
- 用3個步驟實現響應式網頁設計
- 遇見CSS3濾鏡
- 關于CSS3濾鏡的碎念
- 用純CSS3繪制萌系漫畫人物動態頭像
- CSS3新的鼠標樣式介紹
- 用HTML5獻上愛的3D玫瑰
- 對HTML5 Device API相關規范的解惑
- 如何使用HTML5實現拍照上傳應用
- 2012第一季度國外HTML5移動開發趨勢
- HTML5新特性:范圍樣式
- 百度開發者大會-《用HTML5新特性開發移動App》PPT分享
- Chrome 19對于HTML5最新支持的動態:電池狀態API,全屏API,震動API,語音API
- 遇見Javascript類型數組(Typed Array)
- 用HTML5 Audio API開發游戲音樂
- 用HTML5實現人臉識別
- 用Javascript實現人臉美容
- Chrome 20對于HTML5最新支持的動態:顏色輸入,網絡信息API,CSS著色器
- 用HTML5實現手機搖一搖的功能
- 用HTML5實現iPad應用無限平滑滾動
- 用非響應式設計構建跨端Web App
- 了解SVG
- HTML5圖像適配介紹
- HTML5安全:內容安全策略(CSP)簡介
- HTML5安全:CORS(跨域資源共享)簡介
- 用CSS3 Region和3D變換實現書籍翻頁效果
- 談談移動App的思維誤區
- Chrome新特性:文件夾拖拽支持
- 《關注HTML5安全》
- HTML5安全風險詳析之一:CORS攻擊
- HTML5安全風險詳析之二:Web Storage攻擊
- HTML5圖像適配最新進展:響應式圖片規范草案
- HTML5移動Web App相關標準狀態及路線圖
- HTML5安全風險詳析之三:WebSQL攻擊
- Chrome引入WebRTC支持視頻聊天App
- HTML5安全風險詳析之四:Web Worker攻擊
- HTML5安全風險詳析之五:劫持攻擊
- HTML5安全風險詳析之六:API攻擊
- HTML5安全攻防詳析之七:新標簽攻擊
- 在iOS Safari中播放離線音頻
- 使用WebRTC實現遠程屏幕共享
- Firefox、Android、iOS遇見WebRTC
- HTML5光線傳感器簡介
- HTML5安全攻防詳析之八:Web Socket攻擊
- HTML5安全攻防詳析之完結篇:HTML5對安全的改進
- 激動人心!在網頁上通過語音輸入文字 - HTML5 Web Speech API介紹
- Web滾動性能優化實戰
- 用CSS3設計響應式導航菜單
- 用HTML5構建高性能視差網站
- 漫談@supports與CSS3條件規則
- HTML5下載屬性簡介
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(一)
- 如何開發優秀的HTML5游戲?-迪斯尼《尋找奧茲之路》游戲技術詳解(二)
- 趨勢:Chrome為打包應用提供強大新特性
- 從HTML5移動應用現狀談發展趨勢
- 基于HTML5的Web跨設備超聲波通信方案