跨域资源共享(CORS)是一个W3C规范,它定义了一种浏览器和服务器交互的方式来确定是否允许跨源请求。当Web应用的前端和后端部署在不同的域(或端口、协议)下时,浏览器出于安全考虑会限制前端JavaScript代码访问其他源的资源。为了实现跨域请求,后端服务需要在HTTP响应中包含一些特定的头信息来指示浏览器允许跨域访问。
在Spring Boot项目中,你可以通过以下步骤来配置CORS支持:
1. 使用@CrossOrigin注解
你可以在Controller类或方法上使用@CrossOrigin注解来允许跨域请求。例如:
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://your-frontend-domain.com", allowedMethods = {"GET", "POST"})
public class YourApiController {
// ... 方法定义
}
这个注解将允许来自http://your-frontend-domain.com的GET和POST请求访问这个Controller的所有方法。
2. 全局CORS配置
如果你想要全局配置CORS,而不是在每个Controller或方法上单独配置,你可以创建一个配置类并重写WebMvcConfigurer的addCorsMappings方法:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://your-frontend-domain.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(168000); // 缓存预检请求的结果24小时
}
}
这个配置将允许来自http://your-frontend-domain.com的所有HTTP方法访问应用的任何路径,并允许携带凭证(cookies等)。
3. 自定义CORS过滤器
在某些情况下,你可能需要更细粒度的控制,这时可以创建一个自定义的CORS过滤器:
@Component
public class CustomCorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "http://your-frontend-domain.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, content-type");
chain.doFilter(req, res);
}
}
然后,你需要将这个过滤器注册到Spring Security中(如果你使用了Spring Security):
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomCorsFilter corsFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ... 其他安全配置
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class);
}
}
注意事项:
- 允许跨域请求时要小心,确保只允许必要的源和方法,以防止潜在的安全风险。
- 如果你的应用使用了Spring Security,确保CORS配置与Spring Security的配置兼容。
- 在生产环境中,通常不会允许所有头部(
Access-Control-Allow-Headers: *),而是应该指定具体允许的头部。 - 如果你的应用需要处理带凭证的请求(如cookies或HTTP认证),确保设置
Access-Control-Allow-Credentials为true,并在Access-Control-Allow-Origin中指定具体的域名,而不是使用通配符*。
配置完成后,你的Spring Boot应用应该能够处理来自指定前端域的跨域请求了。记得在测试配置时,使用浏览器的开发者工具查看网络请求的响应头,确保CORS相关的头信息已经正确设置。
一个更简单的CORS配置示例
使用Spring Boot并希望允许所有来源的跨域请求。请注意,出于安全考虑,在生产环境中允许所有来源通常不是一个好主意,但在开发或测试环境中可能是可以接受的。
以下是如何在Spring Boot应用中全局启用CORS的简单步骤:
- 创建一个配置类,并实现
WebMvcConfigurer接口。 - 重写
addCorsMappings方法,以添加CORS映射。
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 CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 添加映射路径,我们这里使用的是"/**",表示对所有的路径都进行处理
registry.addMapping("/**")
// 允许跨域请求的域名或IP,星号代表允许所有
.allowedOrigins("*")
// 请求允许的方法,如POST, GET, PUT, DELETE等
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
// 预检间隔时间
.maxAge(168000)
// 允许头部设置
.allowedHeaders("*")
// 是否允许发送cookie
.allowCredentials(true);
}
}
在这个例子中,我们允许所有来源(*)对所有路径(/**)发起跨域请求,并允许所有HTTP方法(如POST、GET、PUT等)。allowedHeaders("*")允许所有的请求头,而allowCredentials(true)则允许携带凭证(如cookies)的请求。
将上述配置类添加到Spring Boot项目中后,应该能够处理来自任何域的跨域请求了。
请再次强调,允许所有来源的跨域请求在生产环境中是不安全的,应该明确指定允许的域。此外,如果不需要允许携带凭证的请求,也可以将allowCredentials(true)改为allowCredentials(false),这通常是一个更安全的做法。