Spring项目Ajax请求跨域问题解决
什么是跨域
简单的说即为浏览器限制访问A站点下的js代码对B站点下的url进行ajax请求。比如说,前端域名是www.abc.com,那么在当前环境中运行的js代码,出于安全考虑,访问www.xyz.com域名下的资源,是受到限制的。现代浏览器默认都会基于安全原因而阻止跨域的ajax请求,这是现代浏览器中必备的功能。
解决办法
有根据spring的版本不同有不同的解决办法:
在spring的4.2版本以后支持CORS(跨域资源共享),只需要在类或者方法上加入
@CrossOrigin注解来实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14(origins = "http://www,xxx.com";, maxAge = 3600)
("/account")
public class AccountController {
("/{id}")
public Account retrieve(@PathVariable Long id) { // ... }
(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) { // ... }
}maxAge表明在3600秒内,不需要再发送预检验请求,添加@CrossOrigin注解后,不需要在ajax请求上有任何改动即可正常发出请求接收数据。在Spring4.2中除了在controller的类或方法上设置外,还可以设置全局配置:
- 定义一个继承自WebMvcConfigurerAdapter的类
1
2
3
4
5
6
7public class CorsConfigurerAdapter extends WebMvcConfigurerAdapter{
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/*").allowedOrigins("*").allowedMethods("GET", "PUT", "DELETE", "POST");
}
}- 将该类注入到容器中
1
<bean class="com.lemo.web.config.CorsConfigurerAdapter"></bean>
- 将该类注入到容器中
- 定义一个继承自WebMvcConfigurerAdapter的类
在spring的4.2版本之前,可以通过自定义一个拦截器,给请求加上相应的相应头来处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MyCorsFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
String origin = (String) servletRequest.getRemoteHost()+":"+servletRequest.getRemotePort();
response.setHeader("Access-Control-Allow-Origin", "*"); //表明它允许任意连接发起跨域请求,*表示所有网站,可以把*替换为具体的网站
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); //表明它允许GET、POST、OPTIONS、DELETE的外域请求
response.setHeader("Access-Control-Max-Age", "3600"); //表明在3600秒内,不需要再发送预检验请求
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization"); //表明它允许跨域请求包含content-type头
response.setHeader("Access-Control-Allow-Credentials","true"); //设置跨域ajax请求时是否带cookie的设置
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {}
}在
web.xml中配置使拦截器生效,配置完后即可生效1
2
3
4
5
6
7
8
9
10<filter>
<filter-name>cors</filter-name>
<filter-class>com.leimo.filter.myeCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>