SpringMVC
中處理跨域資源共享(CORS)
(學習筆記2020.3.26)
前言:
什麼是跨域資源共享?
CORS
是一種允許當前域的資源(比如html/js/web service)被其他域的腳本請求訪問的機制,通常由於同域安全策略瀏覽器會禁止這種跨域請求。 (詳細介紹) 所謂跨域指的是域名不同或者端口不同或者協議不同,資源會發起一個跨域 HTTP 請求。站點 http://domain-a.com 的某 HTML 頁面訪問http://domain-b.com/test網站資源就會存在跨域問題。從4.2版本開始,
Spring MVC
支持CORS。在Spring Boot應用程序中將控制器方法CORS配置與@CrossOrigin
註釋一起使用不需要任何特定的配置。 可以通過使用自定義方法註冊bean 來定義全局CORS配置。當
html
頁面裏面發起跨域請求時候,瀏覽器控制檯就會報以下錯誤:
Access to XMLHttpRequest at 'http://zhihao.com/list' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
1. 使用註解@CrossOrigin
解決
1.1 @CrossOrigin
介紹:
@CrossOrigin
在類和方法級別上使用。如果找不到匹配的
CORS
配置,則請求將被拒絕。
屬性 | 含義 |
---|---|
value |
指定所支持域的集合,* 表示所有域都支持,默認值爲* 。這些值對應HTTP請求頭中的Access-Control-Allow-Origin |
origins |
同value |
allowedHeaders |
允許請求頭中的header,默認都支持 |
exposedHeaders |
響應頭中允許訪問的header,默認爲空 |
methods |
支持請求的方法,比如GET ,POST ,PUT 等,默認和Controller中的方法上標註的一致。 |
allowCredentials |
是否允許cookie隨請求發送,使用時必須指定具體的域, 默認情況下不會啓用。 |
maxAge |
預請求的結果的有效期,默認30分鐘 |
1.2 使用在類級別上
並且被所有方法繼承
@Controller
@CrossOrigin
@RequestMapping("/test")
public class TestController {
@ResponseBody
@GetMapping("/list")
public List<User> findAll(){
List<User> list = userService.findAll();
System.out.println(list);
return list;
}
}
使用在類上,如果沒有指定屬性,將使用
@CrossOrigin
默認值。
1.3 使用在ap
i方法上
只有這個
api
方法生效可以跨域
@GetMapping("/list")
@CrossOrigin(origins = {"http://zhihao.com"},methods = RequestMethod.GET)
public List<User> findAll(){
List<User> list = userService.findAll();
System.out.println(list);
return list;
}
我們這裏可以指定屬性, 放行來源
http://zhihao.com
的跨域請求,並且只能是GET`請求。
2. 配置類全局配置
創建一個配置
WebConfig
類,實現WebMvcConfigurer 接口
,並重寫addCorsMappings
方法
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //所有請求
.allowedOrigins("*") //允許的來源 `*`所有
.allowedMethods("GET","PUT")
.maxAge(3600); //預請求的結果被客戶端緩存有效期
//.allowCredentials(true) 是否允許cookie隨請求發送
//.allowedHeaders() 允許的請求頭部
}
}
2.1 XML
全局配置
要在XML名稱空間中啓用CORS,可以使用``元素,如以下示例所示:
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="https://domain1.com, https://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="true"
max-age="123" />
<mvc:mapping path="/resources/**"
allowed-origins="https://domain1.com" />
</mvc:cors>
3. CORS
過濾器
您可以通過內置的
CorsFilter
應用CORS
支持。如果您嘗試將CorsFilter與Spring Security一起使用,請記住Spring Security內置了對CORS的支持。
要配置過濾器,請將CorsConfigurationSource傳遞給其構造函數,如以下示例所示:
@Bean
public FilterRegistrationBean corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
//此類提供setOrder方法,可以爲CorsFilter設置排序值
FilterRegistrationBean registrationBean = new FilterRegistrationBean(new CorsFilter(source));
//設置優先級
registrationBean.setOrder(0);
return registrationBean;
}
1