HTML5安全:CORS(跨域資源共享)簡介

前言:像CORS對於現代前端這麼重要的技術在國內基本上竟然不多有人使用和說起,在百度或者Google上搜索CORS,搜到的中文文章基本都是另一種衛星定位技術CORS的介紹,讓我等前端同窗情何以堪(對比起來,用Google搜到的國外文章,基本都是跨域資源共享的介紹,說明了前端技術在國內外環境和發展的巨大差距)。 javascript

        我以前《用HTML5實現人臉識別》這篇文章中提到了「Face.com實現了CORS(跨域資源共享)。CORS系統基本上可讓服務器暴露給其它域上文件的Ajax調用。這是一個偉大的功能,我但願更多的服務可以使用它。」在這篇文章介紹的實現方式裏,咱們能夠自由的使用本身本域的JS代碼經過Ajax來調用Face.comAPI,這是一種很美妙的方式,而在之前咱們很難作到這一點。 php

        由此我將引入和介紹CORS,但願對你們有所幫助。 html

定義 前端

        CORS其實出現時間不短了,它在維基百科上的定義是:跨域資源共享(CORS )是一種網絡瀏覽器的技術規範,它爲Web服務器定義了一種方式,容許網頁從不一樣的域訪問其資源。而這種訪問是被同源策略所禁止的。CORS系統定義了一種瀏覽器和服務器交互的方式來肯定是否容許跨域請求。 它是一個妥協,有更大的靈活性,但比起簡單地容許全部這些的要求來講更加安全。 html5

        而W3C的官方文檔目前仍是工做草案,可是正在朝着W3C推薦的方向前進。 java

        簡言之,CORS就是爲了讓AJAX能夠實現可控的跨域訪問而生的。 web

以往的解決方案 api

        之前要實現跨域訪問,能夠經過JSONP、Flash或者服務器中轉的方式來實現,可是如今咱們有了CORS。 跨域

        CORS與JSONP相比,無疑更爲先進、方便和可靠。 瀏覽器

        一、 JSONP只能實現GET請求,而CORS支持全部類型的HTTP請求。

        二、 使用CORS,開發者可使用普通的XMLHttpRequest發起請求和得到數據,比起JSONP有更好的錯誤處理。

        三、 JSONP主要被老的瀏覽器支持,它們每每不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS(這部分會在後文瀏覽器支持部分介紹)。

詳細內容

        要使用CORS,咱們須要瞭解前端和服務器端的使用方法。

        一、  前端

        之前咱們使用Ajax,代碼相似於以下的方式:

[html]  view plain copy
  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "/hfahe", true);  
  3. xhr.send();  

        這裏的「/hfahe」是本域的相對路徑。

        若是咱們要使用CORS,相關Ajax代碼可能以下所示:

[html]  view plain copy
  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "http://blog.csdn.net/hfahe", true);  
  3. xhr.send();  

        請注意,代碼與以前的區別就在於相對路徑換成了其餘域的絕對路徑,也就是你要跨域訪問的接口地址。

        咱們還必須提供瀏覽器回退功能檢測和支持,避免瀏覽器不支持的狀況。



  
  
  
  

  

  

   
   
   
   
   

  
[html] view plain copy
  1. function createCORSRequest(method, url) {  
  2.   var xhr = new XMLHttpRequest();  
  3.   if ("withCredentials" in xhr) {  
  4.     // 此時即支持CORS的狀況  
  5.     // 檢查XMLHttpRequest對象是否有「withCredentials」屬性  
  6.     // 「withCredentials」僅存在於XMLHTTPRequest2對象裏  
  7.     xhr.open(method, url, true);  
  8.    
  9.   } else if (typeof!= "undefined") {  
  10.    
  11.     // 不然檢查是否支持XDomainRequest,IE8和IE9支持  
  12.     // XDomainRequest僅存在於IE中,是IE用於支持CORS請求的方式  
  13.     xhr = new XDomainRequest();  
  14.     xhr.open(method, url);  
  15.    
  16.   } else {  
  17.    
  18.     // 不然,瀏覽器不支持CORS  
  19.     xhr = null;  
  20.    
  21.   }  
  22.   return xhr;  
  23. }  
  24.    
  25. var xhr = createCORSRequest('GET', url);  
  26. if (!xhr) {  
  27.   throw new Error('CORS not supported');  
  28. }  

        如今若是直接使用上面的腳本進行請求,會看到瀏覽器裏控制檯的報錯以下:

        錯誤顯示的很明顯,這是由於咱們還未設置Access-Control-Allow-Origin頭。

        二、  服務器

        服務器端對於CORS的支持,主要就是經過設置Access-Control-Allow-Origin來進行的。若是瀏覽器檢測到相應的設置,就能夠容許Ajax進行跨域的訪問。

        HTTP 頭的設置方法有不少,http://enable-cors.org/這篇文章裏對各類服務器和語言的設置都有詳細的介紹,下面咱們主要介紹Apache和PHP裏的設置方法。

        Apache:Apache須要使用mod_headers模塊來激活HTTP頭的設置,它默認是激活的。你只須要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入如下內容便可:

[html]  view plain copy
  1. Header set Access-Control-Allow-Origin *  

        PHP:只須要使用以下的代碼設置便可。

[html]  view plain copy
  1. <?php  
  2.  header("Access-Control-Allow-Origin:*");  

        以上的配置的含義是容許任何域發起的請求均可以獲取當前服務器的數據。固然,這樣有很大的危險性,惡意站點可能經過XSS攻擊咱們的服務器。因此咱們應該儘可能有針對性的對限制安全的來源,例以下面的設置使得只有http://blog.csdn.net這個域才能跨域訪問服務器的API。

[html]  view plain copy
  1. Access-Control-Allow-Origin: http://blog.csdn.net  

瀏覽器支持狀況


        上圖爲各瀏覽器對於CORS的支持狀況(綠色爲支持,數據來源:http://caniuse.com/cors),看起來至關樂觀。主流瀏覽器都已基本提供對跨域資源共享的支持,因此,CORS纔會在國外使用的如此廣泛。

        上文曾經提到,IE8和IE9在某種程度上能夠經過XDomainRequest來提供一樣功能的支持。

使用案例

        目前國外支持CORS的平臺有不少,例如:

        Google APIClient Library for JS

        Google CloudStorage

        Face.com API

將來

        從全部的瀏覽器都支持來看,CORS將成爲將來跨域訪問的標準解決方案。不管是本身服務器間的跨域訪問,仍是開放平臺爲第三方提供API,都將採用這種統一的解決方案,由於它簡單、高效,受到全部主流瀏覽器的支持。它很是重要,也會讓咱們的網絡變得更加開放。

參考文章

        IE10中的CORS forXHR

        USING CORS

        原創文章,轉載請註明:來自蔣宇捷的博客(http://blog.csdn.net/hfahe)

相關文章
相關標籤/搜索