后端必看!Spring Boot3 跨域难题的五种破局之道

你在 Spring Boot3 开发中遇到过跨域问题吗?相信不少后端开发小伙伴都有过这样的经历:精心编写的接口,在前端调用时却突然报错,页面控制台跳出一堆关于跨域的错误提示,让人抓耳挠腮。别着急,今天就给你讲讲 Spring Boot3 中五种实现跨域操作的方式,帮你轻松解决这个头疼的问题!

在当今前后端分离的开发模式下,前端代码和后端代码往往运行在不同的域名、端口下。当浏览器从一个域名的网页去请求另一个域名的资源时,出于安全策略,浏览器会限制这种跨源请求,这就是跨域问题的由来。而 Spring Boot3 作为当下热门的后端开发框架,在开发过程中也难免会遇到跨域问题。接下来,咱们就深入了解下五种解决它的有效方式。

使用@CrossOrigin注解

最直接、简单的方式就是使用@CrossOrigin注解。你可以直接在 Controller 类或者具体的请求处理方法上使用它。比如,在你的 Controller 类上添加@CrossOrigin(origins = "*"),这就表示允许所有来源的请求进行跨域访问 。不过在生产环境中,出于安全考虑,最好不要使用*,而是指定具体的域名,像@CrossOrigin(origins = "http://example.com"),只允许http://example.com这个域名下的请求跨域访问。如果只是某个接口需要跨域,那就在对应的方法上添加这个注解,比如:

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://allowed-domain.com")
    @GetMapping("/data")
    public String getData() {
        return "Some data";
    }
}

这种方式灵活方便,适用于只需要对部分接口开启跨域支持的场景。

全局配置 CORS

如果你希望对所有接口统一配置跨域策略,那可以创建一个配置类实现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("GET", "POST", "PUT", "DELETE")
               .allowedHeaders("*")
               .allowCredentials(true)
               .maxAge(3600);
    }
}

这里addMapping("/**")表示对所有路径都应用 CORS 配置,allowedOrigins("*")允许所有来源访问,allowedMethods指定了允许的 HTTP 方法,allowedHeaders指定了允许的 HTTP 头部,allowCredentials(true)表示允许携带凭证,maxAge(3600)设置了预检请求的有效期为 3600 秒。当然,在实际生产中,allowedOrigins还是要指定具体域名更安全。这种全局配置方式,能让整个项目的跨域处理更加规范、统一。

使用 Filter 实现 CORS

通过实现Filter接口,我们也能自定义 CORS 的处理逻辑。首先创建一个 Filter 类,示例如下:

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CorsFilter 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", "*");
        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");
        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<CorsFilter> corsFilterRegistrationBean() {
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CorsFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

在 Filter 中,我们通过设置响应头来处理跨域,这种方式能让我们对跨域逻辑有更细致的控制,适用于需要特殊处理跨域响应头的场景。

使用拦截器(Interceptor)

创建拦截器也是解决跨域问题的一种方式。先创建一个拦截器类,实现HandlerInterceptor接口:

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

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) throws Exception {
        response.setHeader("Access-Control-Allow-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");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

接着在配置类中注册拦截器:

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 InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CorsInterceptor())
               .addPathPatterns("/**");
    }
}

拦截器允许我们在请求处理之前或之后添加逻辑,在preHandle方法中设置跨域响应头,实现对跨域的处理。这种方式适用于需要更复杂 CORS 逻辑,比如结合用户认证等其他业务逻辑一起处理的场景。

通过响应体(Response Body)设置 CORS

在 Controller 的方法中,我们还可以通过HttpServletResponse对象来设置
Access-Control-Allow-Origin等 CORS 相关的 HTTP 头。示例代码如下:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
public class MyController {

    @GetMapping("/data")
    public void getData(HttpServletResponse response) throws IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.getWriter().write("Some data");
    }
}

不过这种方式相对前面几种来说比较繁琐,而且如果有多个接口都需要设置,很容易遗漏某些必要的头信息,导致 CORS 配置不完整,所以在实际开发中,一般作为备用方式。

总结

以上就是 Spring Boot3 中五种实现跨域操作的方式啦!每种方式都有其适用场景,你可以根据项目的实际需求来选择合适的方法。希望这些内容能帮助你顺利解决跨域问题。如果你在实践过程中有任何新的发现、问题,欢迎在评论区分享、交流,也别忘了点赞、收藏这篇文章,方便以后随时查看!

原文链接:,转发请注明来源!