SpringBoot设置跨域的几种方式

本文介绍了在SpringBoot中设置跨域的多种方法,包括针对单个Controller和全局跨域的解决方案。全局跨域配置涵盖了使用Filter、CorsConfiguration、WebMvcConfigurer接口以及自定义拦截器来修改响应头。通过这些方法,可以有效地处理跨域请求限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单个Controller及方法:

@CrossOrigin作为一个强大的注解,特点就是不仅支持在controller中设置,还支持方法级注解。而最简单也最直接的方法,那就是在controller中直接加入。

@CrossOrigin(origins = "*",allowCredentials = "true")

全局跨域:

@CrossOrigin虽然支持跨域,但是若想要全局配置,未免太过繁琐。这时候可以尝试以下方式。

1. 过滤器Filter

通过自定义自己的OriginFilter,实现javax.servlet.Filter接口里的doFilter方法,并声明为Component组件,贴出关键代码如下:

@Component
@WebFilter(urlPatterns = "/*", filterName = "CorsFilter")
public class CorsFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest reqs = (HttpServletRequest) req;
        String curOrigin = reqs.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", curOrigin == null ? "true" : curOrigin);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    }
 
 
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("CorsFilter  init");
    }
 
    @Override
    public void destroy() {}
}

2. 设置CorsConfiguration

	@Configuration
	public class GlobalCORSConfiguration {
	    private CorsConfiguration buildConfig() {
	        CorsConfiguration corsConfiguration = new CorsConfiguration();
	        corsConfiguration.addAllowedOrigin("*");
	        corsConfiguration.addAllowedHeader("*");
	        corsConfiguration.addAllowedMethod("*");
	        corsConfiguration.setAllowCredentials(true);
	        return corsConfiguration;
	    }
	 
	    @Bean
	    public CorsFilter corsFilter() {
	        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
	        source.registerCorsConfiguration("/**", buildConfig());
	        return new CorsFilter(source);
	    }
	 
	}

3. WebMvcConfigurer

在spring2.0中,通过自定义的WebMvcConfigurer可以让我们进一步地自定义自己的web项目,同样的,我们可以在这处理相关的跨域问题。首先,我们需要创建一个配置类,让它继承自WebMvcConfigurer,同时使用@Configuration注解标记该配置类。然后重写它的addCorsMappings即可。

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurer{
 
   @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*")
                .allowCredentials(true).allowedMethods("*").maxAge(3600);
    }
}

4. 自定义拦截器重写请求

`此外,我们还可以自定义一个拦截器,通过在preHandle中拦截到的HttpServletResponse,对header重新进行设置。然后在的WebMvcConfigurer中,通过重写addInterceptors方法添加该拦截器即可。

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CorsInterceptor implements HandlerInterceptor {

    /**
     * preHandle在执行Controller之前执行,返回true,则继续执行Contorller
     * 返回false则请求中断。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o)
            throws Exception {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        //只有返回true才会继续向下执行,返回false取消当前请求
        long startTime = System.currentTimeMillis();
        httpServletRequest.setAttribute("startTime", startTime);
        return true;
    }

    /**
     * postHandle是在请求执行完,但渲染ModelAndView返回之前执行
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
            ModelAndView modelAndView) throws Exception {
        long startTime = (Long) httpServletRequest.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        long executeTime = endTime - startTime;
        StringBuilder sb = new StringBuilder(1000);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        sb.append("-----------------------").append(date).append("-------------------------------------\n");
        sb.append("URI       : ").append(httpServletRequest.getRequestURI()).append("\n");
        sb.append("CostTime  : ").append(executeTime).append("ms").append("\n");
        sb.append("-------------------------------------------------------------------------------");
        System.out.println(sb.toString());
    }

    /**
     * afterCompletion是在整个请求执行完毕后执行
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
            Object o, Exception e) throws Exception {
    }

}

在WebConfig 中注册

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CorsInterceptor()).addPathPatterns("/**");
    }
}
### Spring Boot 中解决 CORS 请求的五种方法 #### 方法一:使用 `@CrossOrigin` 注解 在 Controller 类或具体的方法上添加 `@CrossOrigin` 注解,能够快速有效地处理问题。该注解支持设置多个参数,如允许的源地址、HTTP 方法以及自定义头部。 ```java @RestController @RequestMapping("/api") public class MyController { @CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST}) @GetMapping("/data") public String getData() { return "Data"; } } ``` 这种方法适用于小型项目中的单个接口或少数几个接口[^1]。 #### 方法二:通过配置类实现全局 CORS 支持 创建一个继承自 `WebMvcConfigurer` 的配置类,并重写其中的相关方法来指定全局范围内的策略。 ```java @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*"); } } ``` 这种方式适合于大型项目的统一管理需求[^3]。 #### 方法三:利用 Filter 进行拦截并响应预检请求 编写自定义过滤器,在每次 HTTP 请求到达之前对其进行检查;对于 OPTIONS 预检请求,则返回合适的响应头信息以告知客户端服务器端愿意接受来自任何地方的连接尝试。 ```java @Component public class SimpleCORSFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "authorization, content-type"); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { filterChain.doFilter(req, res); } } } ``` 这种做法灵活性较高,尤其当需要更细粒度地控制哪些路径应该被允许时非常有用。 #### 方法四:基于 Security Config 实现安全上下文下的 CORS 控制 如果应用程序已经集成了 Spring Security 组件,则可以在其基础上进一步增强安全性的同时也完成对 CORS 行为的规定: ```java @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() .csrf().disable(); } @Bean CorsConfigurationSource corsConfigurationSource() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 是否允许发送Cookie凭证信息,默认false config.addAllowedOriginPattern("*"); // 允许所有的名访问 config.setMaxAge(3600L); // 设置缓存时间(秒) config.addAllowedHeader("*"); // 允许所有类型的header字段 config.addAllowedMethod("*"); // 允许所有的Http Method source.registerCorsConfiguration("/**", config); return source; } } ``` 这有助于确保即使启用了严格的认证机制也不会影响到正常的站资源共享操作。 #### 方法五:借助第三方库简化 CORS 处理逻辑 除了上述四种内置方式外,还可以考虑引入专门针对 RESTful API 设计的开源工具包——例如 spring-cloud-starter-gateway 或者 resilience4j-circuitbreaker ——它们往往自带完善的 CORS 解决方案,从而减少开发者自行编码的工作量。 以上就是关于如何在 Spring Boot 应用程序内有效应对 CORS 问题的主要途径概述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值