Web开发中,我们经常会遇到跨域的问题,一般来说解决方案有:jsonp,iframe,CORS(Cross-origin Resource Share)等。
CORS与jsonp的区别:
1. jsonp只能实现GET请求,CORS支持所有类型的HTTP请求.
2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起jsonp有更好的错误处理方式.
3. jsonp主要被老浏览器支持,它们一般不支持CORS,大多数现在的浏览器都能支持CORS(目前ie8以下还不能被支持).
配置方法 一
新建一个项目,修改index.ftl,发送一个ajax请求
<!DOCTYPE html>
<html>
<head>
<title>Spring Boot FreeMarker</title>
<link href="/css/index.css" rel="styleSheet" />
</head>
<body>
<center>
<img alt="图片" src="/images/1519656836104.jpg" height="300"/>
<p id="title">${title}</p>
</center>
<script type="text/javascript" src="/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$('#title').click(function() {
$.ajax({
url : "http://127.0.0.1:8081/api/get",
type : "POST",
data : {
name : "访问8081端口测试跨域"
},
success : function(data, status, xhr) {
console.log(status);
console.log(xhr);
console.log(data);
}
});
});
</script>
</body>
</html>
写一个测试用的Controller
@RestController
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/get")
public HashMap<String, Object> get(@RequestParam String name) {
HashMap<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("title", "CORS Test");
hashMap.put("name", name);
return hashMap;
}
}
配置此项目启动端口为8080
然后创建一个新项目,新建CorsConfiguration.java类
@Configuration
public class CorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8080");
}
};
}
}
增加测试Controller
@RestController
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/get")
public HashMap<String, Object> get(@RequestParam String name) {
HashMap<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("title", "CORS Test");
hashMap.put("name", name);
return hashMap;
}
}
修改此项目端口号为8081,启动该项目与之前端口号为8080的项目
访问测试地址8080测试地址,点击hello world
标题
打开浏览器F12调试窗口的Console选项,我们能看到输出如下
是我们后启用的8081端口服务中反馈的输出,实现跨域OK.
配置方法二
继承WebMvcConfigurerAdapter类
我们先注掉之后端口为8081的配置类代码
@Configuration
public class CorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8080");
}
};
}
}
此时访问测试地址8080测试地址,点击hello world
标题,可以看到控制台返回的是
跨域访问失效
我们新建一个类CorsConfiguration2.java
@Configuration
public class CorsConfiguration2 extends WebMvcConfigurerAdapter {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8080");
}
}
访问测试地址8080测试地址,点击hello world
标题,和之前一样跨域OK.
配置方法三
注解方式,实现细粒度跨域设置
我们将上一部配置文件也注掉
@Configuration
public class CorsConfiguration2 extends WebMvcConfigurerAdapter {
public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/api/**").allowedOrigins("http://127.0.0.1:8080");
}
}
此时打开测试链接会无法跨域访问,我们修改ApiController.java类
@RestController
@RequestMapping("/api")
public class ApiController {
@CrossOrigin(origins = "http://127.0.0.1:8080")
@RequestMapping(value = "/get")
public HashMap<String, Object> get(@RequestParam String name) {
HashMap<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("title", "CORS Test");
hashMap.put("name", name);
return hashMap;
}
}
访问测试地址8080测试地址,点击hello world
标题,和之前一样跨域OK.
用注解配置可以在方法上进行跨域设置,比如Controller中各个方法对不同域名点击过来的访问提供不同的访问策略,更好更安全进行跨域设置.