CORS with Spring MVC--转
原文地址:http://dontpanic.42.nl/2015/04/cors-with-spring-mvc.html
CORS with Spring MVC
In this blog post I will explain how to implement Cross-Origin Resource Sharing (CORS) on a Spring MVC backend.
CORS is a W3C spec that allows cross-domain communication from the browser. Whenever a request is made from http://www.domaina.com to http://www.domainb.com, or even from http://localhost:8000 to http://localhost:9000, you will need to implement CORS on your backend.
To allow CORS we need to add the following headers to all Spring MVC responses:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Methods: GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Max-Age: 3600
The easiest way to do this is by creating an interceptor:
public class CorsInterceptor extends HandlerInterceptorAdapter {
public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader(CREDENTIALS_NAME, "true");
response.setHeader(ORIGIN_NAME, "http://localhost:9000");
response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader(MAX_AGE_NAME, "3600");
return true;
}
}
Then we register this interceptor in our web configuration:
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CorsInterceptor());
}
...
}
Now all GET requests will be handled correctly.
Modification requests
Whenever we do a modification request (POST, PUT, DELETE), our browser will first send a 'preflight' OPTIONS request. This is an extra security check to see if you can modify data. Because Spring MVC ignores OPTIONS requests by default, we will not get a CORS compliant response. We can overwrite this configuration as follows:
When using a Java configuration, in the DispatcherServletInitializer:
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
super.customizeRegistration(registration);
}
Or in the web.xml:
<servlet>
<servlet-name>yourServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Now we can write a simple handler for OPTIONS requests:
@Controller
public class OptionsController {
@RequestMapping(method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
}
This controller handles all OPTIONS requests, sending back a NO_CONTENT response with the desired CORS headers due to our interceptor. Now that OPTIONS respond correctly, the PUT, POST and DELETE will also work correctly.
Congratulations, you now have a CORS compliant Spring MVC backend :)
Multiple origins
Sometimes you have a backend service that is used by multiple applications and thus serves multiple origins. With some minor code changes we can implement this feature:
public class CorsInterceptor extends HandlerInterceptorAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(CorsInterceptor.class);
public static final String REQUEST_ORIGIN_NAME = "Origin";
public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String METHODS_NAME = "Access-Control-Allow-Methods";
public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
private final List<String> origins;
public CorsInterceptor(String origins) {
this.origins = Arrays.asList(origins.trim().split("( )*,( )*"));
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader(CREDENTIALS_NAME, "true");
response.setHeader(METHODS_NAME, "GET, OPTIONS, POST, PUT, DELETE");
response.setHeader(HEADERS_NAME, "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader(MAX_AGE_NAME, "3600");
String origin = request.getHeader(REQUEST_ORIGIN_NAME);
if (origins.contains(origin)) {
response.setHeader(ORIGIN_NAME, origin);
return true; // Proceed
} else {
LOGGER.warn("Attempted access from non-allowed origin: {}", origin);
// Include an origin to provide a clear browser error
response.setHeader(ORIGIN_NAME, origins.iterator().next());
return false; // No need to find handler
}
}
}
All we do now is checking if our request origin is in the list of allowed origins and echo it back into the response. Thus if somebody makes a request from 'domain-a.com' we return back that same 'domain-a.com' as allowed origin, while for 'domain-b.com' we return 'domain-b.com'.
Because the list of allowed origins is provided as string, we can simply define our origins in a properties file:
cors.origins=http://www.domain-a.com,http://www.domain-b.com
CORS with Spring MVC--转的更多相关文章
- enable cors in spring mvc with swagger
a. In controller add @CrossOrigin(origins = "http://localhost:8080") b. In mvc-servlet.xml ...
- 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求
论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...
- spring MVC cors跨域实现源码解析
# spring MVC cors跨域实现源码解析 > 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就 ...
- Java - Spring MVC 实现跨域资源 CORS 请求
拦截器设置响应头 这种方式原理就是利用拦截器在方法执行前,我们增加请求的响应头,用来支持跨域请求.这种方案是可行的,大部分都是采用这种方案.我当时也是打算采用这种方案,直到我发现原来 Spring 框 ...
- Spring MVC使用Cors实现跨域
在开发APP过程中,APP调用后端接口有跨域的问题,只要在spring-mvc.xml 文件中加入下面的配置即可: <!-- 解决API接口跨域问题配置 Spring MVC 版本必须是 4.2 ...
- Spring MVC 4.2 CORS 跨域访问
跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...
- Spring MVC 实现跨域资源 CORS 请求
说到 AJAX 跨域,很多人最先想到的是 JSONP.的确,JSONP 我们已经十分熟悉,也使用了多年,从本质上讲,JSONP 的原理是给页面注入一个 <script>,把远程 JavaS ...
- Spring MVC配置CORS(解决跨域请求)
1. CORS 简介 同源策略(same origin policy)是浏览器安全的基石.在同源策略的限制下,非同源的网站之间不能发送 ajax 请求的. 为了解决这个问题,w3c 提出了跨源资源共享 ...
- Spring MVC 后端接口支持跨域CORS调用
Spring MVC 从4.2版本开始增加了对CORS的支持,可以全局配置,也可以对类或方法配置:可以通过Java代码,也可以通过xml配置方式. 对于低版本的Spring MVC 可以通过Filte ...
随机推荐
- /application/nginx/sbin/nginx -h
[root@web03 ~]# /application/nginx/sbin/nginx -h nginx version: nginx/1.6.3Usage: nginx [-?hvVtq] [- ...
- SpringBoot项目maven 打包时跳过测试
在打包spring boot项目时,如果测试用例特别多,打包时间会增加: 而且测试用例有时忘记了做相应修改,在打包时则会报错而终止打包,就很烦. 所以这时会想在打包时跳过测试,大致有2种方法: 方法一 ...
- nginx和apache作为webserver的差别
1.两者所用的驱动模式不同. nginx使用的是epoll的非堵塞模式事件驱动. apache使用的是select的堵塞模式事件驱动. 2.fastcgi和cgi的差别 当用户请求web服务的时候.w ...
- [LeetCode]Subsets II生成组合序列
class Solution {//生成全部[不反复]的组合.生成组合仅仅要採用递归,由序列从前往后遍历就可以. 至于去重,依据分析相应的递归树可知.同一个父节点出来的两个分支不能一样(即不能与前一个 ...
- C++基础之全局变量
C++的水比較深,之前我一直以为C++的全局变量会像其它语言一样,很easy仅仅要在头文件里,定义一个变量就可以,比方以下的test.h: #ifndef _TEST_H #define _TEST_ ...
- [PHP]怎样在SAE的CodeIgniter项目中隐藏掉index.php
第一步:改动项目根文件夹的config.yaml文件.加入例如以下内容: handle: - rewrite: if(!is_dir() && !is_file() && ...
- 里根上台时国债只占GDP的30%
学里根是刻舟求剑,关键是钱从哪来 5 里根主要靠借钱,这是冷战红利,美国打完二战国债占了GDP的120%,然后总量就没怎么增加,但战后GDP快速增长,结果国债占GDP的比例连续下降,打越战登月石油危 ...
- Pocket英语语法---二、指示代词和不定代词是什么
Pocket英语语法---二.指示代词和不定代词是什么 一.总结 一句话总结: 指示代词:标识人或事物的代词,用来代替前面已提到过的名词 this.these.that.those不定代词:指代不确定 ...
- 8.解决IntelliJ Idea 集成TortoiseSVN 时找不到svn.exe
转自:https://blog.csdn.net/beibeijia125/article/details/70183533?utm_source=blogxgwz9 首先我们可以在http://su ...
- react ---- Router路由的使用和页面跳转
React-Router的中文文档可以参照如下链接: http://react-guide.github.io/react-router-cn/docs/Introduction.html 首先,我们 ...