在Spring Boot 3中,解决跨域请求(CORS,Cross-Origin Resource Sharing)的问题主要有以下几种方式:
1. 使用@CrossOrigin
注解
你可以直接在Controller类或者具体的请求处理方法上使用@CrossOrigin
注解来允许跨域请求。
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})
public class MyController { @GetMapping("/myEndpoint") public String myEndpoint() { return "Hello, CORS!"; }
}
在这个例子中,@CrossOrigin
注解被添加到了控制器类上,表示这个控制器下的所有方法都允许来自http://example.com
的GET和POST请求。你也可以将注解添加到特定的方法上,以对该方法应用CORS配置。
2. 全局配置CORS
如果你希望全局配置CORS,而不是在每个Controller或方法上单独配置,你可以创建一个配置类来实现WebMvcConfigurer
接口,并重写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 CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { // 添加映射路径 registry.addMapping("/**") .allowedOrigins("*") // 允许哪些域的请求,星号代表允许所有 .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许的方法 .allowedHeaders("*") // 允许的头部设置 .allowCredentials(true) // 是否发送cookie .maxAge(168000); // 预检间隔时间 }
}
在这个配置中,addMapping("/**")
表示对所有的路径都应用CORS配置。allowedOrigins("*")
表示允许所有来源的访问,这在生产环境中可能不是最佳实践,通常你会指定具体的域名。allowedMethods
定义了允许的HTTP方法,allowedHeaders
定义了允许的HTTP头部,allowCredentials(true)
表示是否允许携带凭证(cookies, HTTP认证及客户端SSL证明等),maxAge
则用于设置预检请求的有效期。
3. 使用Filter实现CORS
你也可以通过实现Filter
接口来自定义CORS处理逻辑。
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; public class SimpleCorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "http://example.com"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {}
}
然后需要在配置类中注册这个Filter。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class FilterConfig { @Bean public FilterRegistrationBean<SimpleCorsFilter> corsFilter() { FilterRegistrationBean<SimpleCorsFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new SimpleCorsFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; }
}
4. 使用拦截器(Interceptor)
如果需要更复杂的CORS逻辑,你可以创建一个拦截器来处理CORS请求。拦截器允许你在请求处理之前或之后添加逻辑。
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { response.setHeader("Access-Control-Allow-Origin", "http://example.com"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.setHeader("Access-Control-Allow-Headers", "*"); // 其他CORS相关的响应头设置 return true; }
}
然后,你需要在配置类中注册这个拦截器:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration
public class WebConfig implements WebMvcConfigurer { @Autowired private CorsInterceptor corsInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(corsInterceptor).addPathPatterns("/**"); }
}
- 当设置
allowedHeaders("*")
时,实际上浏览器会发送实际请求头而不是*
。出于安全考虑,最好明确指定允许的头部。 - 在生产环境中,确保不要过于宽松地配置CORS,只允许必要的源和方法。
- 如果你的应用部署在代理服务器后面(如Nginx或Apache),可能还需要在代理服务器上配置CORS。