遇上浏览器跨域问题怎么办?
出于安全原因,浏览器禁止 Ajax 调用驻留在当前原点之外的资源。例如,当你在一个标签中检查你的银行账户时,你可以在另一个选项卡上拥有 EVILL 网站。来自 EVILL 的脚本不能够对你的银行 API 做出 Ajax 请求(从你的帐户中取出钱!)使用您的凭据。
跨源资源共享(CORS)是由大多数浏览器实现的 W3C 规范,允许你灵活地指定什么样的跨域请求被授权,而不是使用一些不太安全和不太强大的策略,如 IFRAME 或 JSONP。
Spring Framework 4.2 GA 为 CORS 提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以 springMVC 的版本要在 4.2 或以上版本才支持 @CrossOrigin
1. controller 配置 CORS
1.1 controller 方法的 CORS 配置,您可以向 @RequestMapping 注解处理程序方法添加一个 @CrossOrigin 注解,以便启用 CORS(默认情况下,@CrossOrigin 允许在 @RequestMapping 注解中指定的所有源和 HTTP 方法):
其中 @CrossOrigin 中的 2 个参数:
1.2 为整个 controller 启用 @CrossOrigin
在这个例子中,对于 retrieve() 和 remove() 处理方法都启用了跨域支持,还可以看到如何使用 @CrossOrigin 属性定制 CORS 配置。
1.3 同时使用 controller 和方法级别的 CORS 配置,Spring 将合并两个注释属性以创建合并的 CORS 配置。
1.4 如果您正在使用 Spring Security,请确保在 Spring 安全级别启用 CORS,并允许它利用 Spring MVC 级别定义的配置。
2. 全局 CORS 配置
JavaConfig
使整个应用程序的 CORS 简化为:
您可以轻松地更改任何属性,以及仅将此 CORS 配置应用到特定的路径模式:
如果您正在使用 Spring Security,请确保在 Spring 安全级别启用 CORS,并允许它利用 Spring MVC 级别定义的配置。
3. XML命名空间
还可以将 CORS 与 MVC XML 命名空间配置。
a) 如果整个项目所有方法都可以访问,则可以这样配置;此最小 XML 配置使 CORS 在 /** 路径模式具有与 JavaConfig 相同的缺省属性:
其中 * 表示匹配到下一层;** 表示后面不管有多少层,都能匹配。
如:
这个可以匹配到的路径有:
不能匹配的:
因为 * 只能匹配到下一层路径,如果想后面不管多少层都可以匹配,配置如下:
请求路径有 /api/,方法示例如下:
c) 如果使用 Spring Security,不要忘记在 Spring 安全级别启用 CORS:
4. How does it work?
CORS 请求(包括预选的带有选项方法)被自动发送到注册的各种 HandlerMapping 。它们处理 CORS 准备请求并拦截 CORS 简单和实际请求,这得益于 CorsProcessor 实现(默认情况下默认 DefaultCorsProcessor 处理器),以便添加相关的 CORS 响应头(如 Access-Control-Allow-Origin)。 CorsConfiguration 允许您指定 CORS 请求应该如何处理:允许 origins, headers, methods 等。
a) AbstractHandlerMapping 类的 setCorsConfiguration() 方法允许指定一个映射,其中有几个 CorsConfiguration 映射在路径模式上,比如 /api/**。
b) 子类可以通过重写 AbstractHandlerMapping 类的 getCorsConfiguration(Object, HttpServletRequest) 方法来提供自己的 CorsConfiguration。
c) 处理程序可以实现 CorsConfigurationSource 接口(如 ResourceHttpRequestHandler),以便为每个请求提供一个 CorsConfiguration。
5. 基于过滤器的 CORS 支持
1. 是 springMVC 的版本要在 4.2 或以上版本才支持 @CrossOrigin
2. 非 @CrossOrigin 没有解决跨域请求问题,而是不正确的请求导致无法得到预期的响应,导致浏览器端提示跨域问题。
3. 在 Controller 注解上方添加 @CrossOrigin 注解后,仍然出现跨域问题,解决方案之一就是:
在 @RequestMapping 注解中没有指定 Get、Post 方式,具体指定后,问题解决。
类似代码如下:
参考文章:
1. 官方文档 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
2. http://fanshuyao.iteye.com/blog/2384189
3. https://blog.csdn.net/taiyangnimeide/article/details/78305131
4. https://blog.csdn.net/snowin1994/article/details/53035433