方式一:通过 @CrossOrigin 注解(局部配置)
若你仅需对特定的控制器或者处理方法开启跨域访问,可使用@CrossOrigin注解。
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
// 允许来自http://example.com的跨域请求
@CrossOrigin(origins = "http://example.com")
@GetMapping("/api/data")
public String getData() {
return "这是跨域数据";
}
}
方式二:实现 WebMvcConfigurer(全局配置)
若你要进行全局的跨域配置,可创建一个配置类并实现WebMvcConfigurer接口。
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.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 对所有接口都有效
.allowedOrigins("http://example.com") // 允许访问的客户端域名
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
.allowCredentials(true) // 是否允许携带凭证(如cookie)
.maxAge(3600) // 预检请求的有效期,单位为秒
.allowedHeaders("*"); // 允许的请求头
}
// 另一种配置方式(推荐)
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*"); // 允许所有域名进行跨域调用(注意:在生产环境中需明确指定域名)
config.addAllowedHeader("*"); // 允许任何请求头
config.addAllowedMethod("*"); // 允许任何方法(POST、GET等)
config.setAllowCredentials(true); // 允许携带凭证
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 对所有接口都有效
return new CorsFilter(source);
}
}
方式三:使用 Filter(高级配置)
你还能通过自定义 Filter 来实现更高级的跨域配置。
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CorsFilter 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", request.getHeader("Origin"));
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, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
response.setHeader("Access-Control-Allow-Credentials", "true");
// 处理预检请求
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
}