1, 簡介
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它容許瀏覽器向跨源(協議 + 域名 + 端口)服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。spring
CORS須要瀏覽器和服務器同時支持。它的通訊過程,都是瀏覽器自動完成,不須要用戶參與。對於開發者來講,CORS通訊與同源的AJAX通訊沒有差異,代碼徹底同樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感受。
所以,實現CORS通訊的關鍵是服務器。只要服務器實現了CORS接口,就能夠跨源通訊。json
2, 基本流程
瀏覽器將CORS請求分紅兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
瀏覽器發出CORS簡單請求,只須要在頭信息之中增長一個Origin字段。
瀏覽器發出CORS非簡單請求,會在正式通訊以前,增長一次HTTP查詢請求,稱爲"預檢"請求(preflight)。瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及能夠使用哪些HTTP動詞和頭信息字段。只有獲得確定答覆,瀏覽器纔會發出正式的XMLHttpRequest請求,不然就報錯。跨域
只要同時知足如下兩大條件,就屬於簡單請求。
1) 請求方法是如下三種方法之一:
HEAD
GET
POST
2)HTTP的頭信息不超出如下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain瀏覽器
3, 具體實現(spring boot)安全
/**
* 描述: 使用Filter 處理跨域請求,即CORS(跨來源資源共享)。
*
* @author city space
*
*/
@Configuration
public class SimpleCORS
{
/**
* 設置 跨域請求參數,處理跨域請求
*
* @return
*/
@Bean
public CorsFilter corsFilter()
{
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}服務器
private CorsConfiguration buildConfig()
{
CorsConfiguration corsConfiguration = new CorsConfiguration();cookie
// 容許跨域訪問的域名
corsConfiguration.addAllowedOrigin("*");
// 請求頭
corsConfiguration.addAllowedHeader("*");
// 請求方法
corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
corsConfiguration.addAllowedMethod(HttpMethod.POST);
corsConfiguration.addAllowedMethod(HttpMethod.GET);
corsConfiguration.addAllowedMethod(HttpMethod.PUT);
corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
// 預檢請求的有效期,單位爲秒。
corsConfiguration.setMaxAge(3600L);
// 是否支持安全證書
corsConfiguration.setAllowCredentials(true);app
return corsConfiguration;
}
}cors
4, 配置項解釋
4.1 Access-Control-Allow-Origin
該字段必填。它的值要麼是請求時Origin字段的具體值,要麼是一個*,表示接受任意域名的請求。ui
4.2 Access-Control-Allow-Methods
該字段必填。它的值是逗號分隔的一個具體的字符串或者*,代表服務器支持的全部跨域請求的方法。注意,返回的是全部支持的方法,而不單是瀏覽器請求的那個方法。這是爲了不屢次"預檢"請求。
4.3 Access-Control-Expose-Headers
4.3 該字段可選。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。若是想拿到其餘字段,就必須在Access-Control-Expose-Headers裏面指定。
4.4 Access-Control-Allow-Credentials
該字段可選。它的值是一個布爾值,表示是否容許發送Cookie.默認狀況下,不發生Cookie,即:false。對服務器有特殊要求的請求,好比請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json,這個值只能設爲true。若是服務器不要瀏覽器發送Cookie,刪除該字段便可。
4.5 Access-Control-Max-Age
該字段可選,用來指定本次預檢請求的有效期,單位爲秒。在有效期間,不用發出另外一條預檢請求。
注意: CORS請求發送Cookie時,Access-Control-Allow-Origin只能是與請求網頁一致的域名。同時,Cookie依然遵循同源政策,只有用服務器域名設置的Cookie纔會上傳,其餘域名的Cookie並不會上傳,且(跨源)原網頁代碼中的document.cookie也沒法讀取服務器域名下的Cookie。