在平常的开发工作中,我们经常会遇到跨域的问题。特别是前后端接口联调的时候,经常听到说跨域了。那么,究竟什么是跨域?出现了跨域应该怎么解决?有时我们做的项目,项目都搭建好了,允许跨域都已经配置了,很少遇到跨域的问题。今天,我们总结下什么是跨域及解决方法。
跨域,域即网址,包括协议、域名和端口号,三者中任何一个不同,就是不同的域,由于浏览器的同源策略,出于安全考虑,默认不允许跨域。如一个网页的地址是http:xxx.com 访问 http:.axa.com 的资源,就会产生跨域,导致访问失败,如下图片,即请求接口的时候跨域了,调用报错:
在方法上添加 @CrossOrigin 注解,作用在方法上或者 controller 类上,主要适用于个别接口添加跨域,当需要配置允许跨域的域名、是否携带凭证、预检缓存时间等可以具体设置。代码示例如下:
/**
* 测试跨域
*/
@CrossOrigin // 默认允许所有来源(*)、所有HTTP方法、不携带凭证
@PostMapping("/queryAnswers")
public String test11(@RequestBody QueryVO vo) throws Exception {
return "success";
}
/**
* 细化配置
*/
@CrossOrigin(
origins = {"*"}, //
methods = {RequestMethod.GET, RequestMethod.POST},
allowedHeaders = {*},
exposedHeaders = {*"},
allowCredentials = "true",
maxAge = 3600
)
@PostMapping("/queryAnswers")
public String test11(@RequestBody QueryVO vo) throws Exception {
return "success";
}
(1):新建 WebConfig 类,实现 WebMvcConfigurer 接口
(2):重写 addCorsMappings 方法。
代码示例:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 跨域配置
*/
@Configuration
public class WebConfig implements WebMvcConfigurer
{
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false)
.maxAge(3600);
}
}
解释如下:
.addMapping("/**"):对所有有请求都启用 CORS 配置。
.allowedOrigins("*"):允许访问该资源的外域url。"*" 表示允许所有的域名进行跨域调用。
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS"):指定了允许的HTTP请求方法。允许的方法有 GET、POST、PUT、DELETE 和 OPTIONS。OPTIONS 方法通常用于预检请求,即先发送一个 OPTIONS 判断服务器是否允许跨域。
.allowedHeaders("*"):允许的请求头。"*" 表示允许所有的请求头。
.allowCredentials(false):是否允许携带凭证,Cookie等。
.maxAge(3600):设置预检请求的缓存时间(单位为秒)。这里设置为3600秒,即在一个小时内无需再次发送预检请求。
配置
(1):新建 WebConfig 类,实现 WebMvcConfigurer 接口
(2):新建 CorsFilter Bean
代码如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 通用配置
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
/**
* 跨域配置
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置访问源地址
config.addAllowedOriginPattern("*");
// 设置访问源请求头
config.addAllowedHeader("*");
// 设置访问源请求方法
config.addAllowedMethod("*");
// 有效期 3600秒
config.setMaxAge(3600L);
// 添加映射路径,拦截一切请求
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
return new CorsFilter(source);
}
}
解释如下:
config.setAllowCredentials(true):允许客户端在跨域请求中携带凭证。
config.addAllowedOriginPattern("*"):指定允许访问该资源的源地址模式,*表示允许所有的源地址进行跨域访问。
config.addAllowedHeader("*"):允许的请求头,*表示允许任何请求头。
config.addAllowedMethod("*"):允许的 HTTP 请求方法。* 表示允许所有的 HTTP 请求方法,如 GET、POST、PUT、DELETE等。
config.setMaxAge(3600L):设置预检请求的缓存时间(单位为秒)。这里设置为3600秒,即在一个小时内无需再次发送预检请求。
source.registerCorsConfiguration("/**", config):"/**" 表示匹配所有的 URL 路径,即对服务器的所有请求都应用上述配置的CORS规则。
以上为常用的解决跨域的三种方式。需要对单个接口、部分接口进行跨域配置,可使用 @CrossOrigin 注解。若要对 Spring MVC 应用进行全局跨域配置,且配置需求不是特别复杂,建议使用addCorsMappings方法。若需要对整个应用(包括非 Spring MVC 请求)进行统一的、灵活的跨域配置,建议使用 CorsFilter。