1、介绍

由于安全原因,浏览器禁止AJAX请求不在当前域内的资源。例如,你在一个浏览器标签中检查你的银行账户时,可能在另一个标签中打开了evil.com 。来自evil.com的脚本绝对不可以用AJAX请求你的银行API!

Cross-origin resource sharing (CORS) 是一个W3C specification,大多数浏览器都已经实现了该功能,可以让你以一种弹性的方式指定哪些跨域请求是被授权的,而不是用一些不怎么安全或不怎么强大的手段 -- 如IFRAME或JSONP。

自Spring Framework 4.2开始,CORS已经可以开箱即用啦。CORS请求(包括OPTIONS method)会被自动分发到各种注册过的HandlerMappings。它们会处理CORS的preflight请求,会拦截CORS简单和实际请求 -- 这都是CorsProcessor的一个实现的功劳(默认是DefaultCorsProcessor),以便添加相关的CORS响应头(如 Access-Control-Allow-Origin) -- 基于你提供的CORS配置。

注意:因为CORS请求会被自动分发,所以你不需要改变DispatcherServlet dispatchOptionsRequest 的 init parameter值;其默认值(false)就可以!

2、Controller method CORS configuration -- Controller方法的CORS配置

你可以在你的@RequestMapping注解过的controller method上面添加@CrossOrigin注解,已开启CORS。默认,该注解允许@RequestMapping中指定的所有原始域和HTTP methods。如下:

@RestController
@RequestMapping("/account")
public class AccountController { @CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

也可以为整个controller启用CORS:

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController { @RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

在上面的这个例子中,retrieve()和remove()同时开启了CORS支持,你还可以看到如何使用@CrossOrigin的attributes来定制CORS配置。

还可以同时使用controller级别和method级别的CORS配置;Spring会将二者的attributes结合起来,创建出融合的CORS配置。

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController { @CrossOrigin("http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
} @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}

-- 不要懵,就是正常的请求,只不过是从别的域中发起的。

3、全局CORS配置

除了细粒度的、基于注解的配置,还可以定义全局的CORS配置。类似于使用filters,但可以定义在Spring MVC中,并与细粒度的@CrossOrigin配置相配合。 默认,允许所有的origins和GET、HEAD、POST methods。

3.1、JavaConfig

开启全局的CORS是很简单的:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter { @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}

你可以轻松的修改任何properties,也可以将CORS配置应用到某个特定的path pattern:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter { @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}

3.2、XML namespace

<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>
<mvc:cors>

    <mvc:mapping path="/api/**"
allowed-origins="http://domain1.com, http://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="false"
max-age="123" /> <mvc:mapping path="/resources/**"
allowed-origins="http://domain1.com" /> </mvc:cors>

4、高级定制

CorsConfiguration允许指定如何处理CORS请求:allowed origins、headers、methods等等。

有多种方式实现:

AbstractHandlerMapping#setCorsConfiguration()允许指定一个Map,然后在Map中封入几个CorsConfiguration实例 -- 映射到path patterns,如 /api/** 。

重写AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)即可提供自己的CorsConfiguration 。

handlers可以实现CorsConfigurationSource接口,从而为每个请求提供一个CorsConfiguration实例。--ResourceHttpRequestHandler已经实现了该接口。

5、基于filter的CORS支持

为了在基于filter的安全框架--如Spring Security上面支持CORS,或者在使用其他不支持CORS的库上支持CORS,Spring框架还提供了一个CorsFilter。不过这样的话,就不能使用@CrossOrigin 或者 WebMvcConfigurer#addCorsMappings(CorsRegistry)了,需要注册一个自定义的filter:

import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; public class MyCorsFilter extends CorsFilter { public MyCorsFilter() {
super(configurationSource());
} private static UrlBasedCorsConfigurationSource configurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}

注意:需要确保CorsFilter的顺序先于所有其他的filters,见this blog post,是关于如何配置Spring Boot的。

推荐个链接:

跨域资源共享 CORS 详解

这里

官方链接地址:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html

Spring 4 官方文档学习(十五)CORS支持的更多相关文章

  1. Spring 4 官方文档学习(五)核心技术之SpEL

    题外话 官方文档用evaluate这个单词来描述从表达式中获得实际内容的过程.如果直译的话,应该是评估.估值之类的意思.个人以为翻译成解析更易懂,但parse已经是解析了,为了避免冲突,就只好保留了e ...

  2. Spring 4 官方文档学习(十二)View技术

    关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...

  3. Spring Boot 官方文档学习(一)入门及使用

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  4. Spring boot官方文档学习(一)

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  5. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  6. Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图

    接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolv ...

  7. Spring 4 官方文档学习(十一)Web MVC 框架

    介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...

  8. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)

    题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...

  9. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)

    接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...

  10. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

随机推荐

  1. java泛型编译时被擦除引起多态的破坏,用 桥方法解决此类问题。(java 桥方法)

    在JVM虚拟机中泛型编译的时候,会出现类型擦除.但是,在多态场景中,编译时,擦除方式会出现多态被破坏的可能. 举个栗子: A.java public class A<T> { void g ...

  2. python猜数脚本(电脑猜测)(二分法)

    # coding=utf-8# 猜数# 记录猜数的过程import randomcom_result=[]  #存放电脑结果,数组com_count=0 #存放电脑猜测次数ran=random.ran ...

  3. JavaScript编程总结

    1.   JS加载放在底部 2.   JS和CSS合并,一个页面加载的JS和CSS越少越好 3.   尽量使用变量,页非全局变量. 4.   脚本和DOM交互越少越好,尽量批量修改. 5.   批量修 ...

  4. echarts引入及应用

    1.在官网上下载echarts并引入项目中 <script src="js/echarts.js"></script> 2.给一个DOM作为图表展示的容器, ...

  5. {HDU}{2516}{取石子游戏}{斐波那契博弈}

    题意:给定一堆石子,每个人最多取前一个人取石子数的2被,最少取一个,最后取石子的为赢家,求赢家. 思路:斐波那契博弈,这个题的证明过程太精彩了! 一个重要的定理:任何正整数都可以表示为若干个不连续的斐 ...

  6. 服务器控件中使用<%#...>, JS和html控件中使用<%=...>

    //在服务器控件的属性中,需要用<%#...>来绑定其他控件的ID, 并且要在页面初始方法中,执行Page.DataBind(); <asp:ImageButton ID=" ...

  7. UIImagePickerController的知识点

    1.UIImagePickerController是系统提供的用来获取图片或视频的接口,使用UIImagePickerController类来获取图片的基本步骤如下: a.初始化UIImagePick ...

  8. vc++ 判断文件或是文件夹是否存在,比较好的做法

    #include <windows.h> void main() { //文件或文件夹都可以判断,最后的\\号有无都没关系 !=GetFileAttributes("D:\\My ...

  9. SQL查询所有表,所有列

    1.查询实例中所有数据库 select name,database_id from sys.databases 2.查询数据库中所有表select TABLE_TYPE,TABLE_NAME from ...

  10. 一个页面中显示多个button时总行数计算公式。

    总行数 = (按钮总数 + 每一行按钮数 - 1) / 每一行按钮数. 同理.假设我们要显示一定总数的item.每页固定数量,则总页数为. 总页数 = (总显示数量 + 每页显示的数量 - 1) / ...