SpringBoot应用解决浏览器跨域问题CORS的几种解决方案

项目环境:JDK17,springboot 版本:3.4.5
方式一:通过@CrossOrigin注解方式解决跨域问题(在Controller层使用)

`@CrossOrigin` 注解的可选值包括 `origins`(允许的源)、`allowedHeaders`(允许的请求头)、`exposedHeaders`(暴露的响应头)、`maxAge`(预检请求有效期)、`allowCredentials`(是否允许携带凭证)和 `methods`(允许的HTTP方法)。

/**
 * 通过@CrossOrigin注解方式解决跨域问题
 */
@CrossOrigin(origins = "*")
@RestController
public class DemoController {
    @RequestMapping("/")
    public String index() {
        return "Hello world";
    }
}
方式二:过滤器实现跨域问题
/**
 * 通过过滤器实现跨域问题的配置。
 * 需要实现 jakarta.servlet 下的Filter接口
 */

@Configuration
public class WebFilter implements Filter {
    /**
     * 实现跨域(CORS)支持的过滤器方法。
     * 在每次 HTTP 请求处理之前被调用,用于设置响应头以解决浏览器的跨域限制。
     *
     * @param request  请求对象,表示客户端发送的请求
     * @param response 响应对象,表示服务端返回的响应
     * @param chain    过滤器链对象,用于执行后续的过滤器或目标资源
     * @throws IOException      如果在处理请求或响应时发生 I/O 错误
     * @throws ServletException 如果在处理过程中发生其他 Servlet 错误
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;
        // 允许指定来源跨域访问,可将 "*" 替换为具体的域名
        resp.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        // 允许的 HTTP 方法
        resp.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS");
        // 允许的请求头
        resp.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type, Authorization");
        // 是否允许发送 Cookie
        resp.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        // 暴露给客户端的响应头(可选)
        resp.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "X-Custom-Header");
        //放行过滤链
        chain.doFilter(request, response);
    }

}
方式三:拦截器解决跨域问题

/**
 * 通过拦截器解决跨域问题,实现 HandlerInterceptor 接口
 */
@Component
public class WebInterceptor implements HandlerInterceptor {
    /**
     * @param request  当前HTTP请求
     * @param response 当前HTTP响应
     * @param handler  开始异步执行的处理器(或{@link HandlerMethod}),用于类型和/或实例检查
     * @return true 表示继续执行后续拦截器或目标方法,false 表示中断后续处理
     * @throws Exception 方法执行异常抛出
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 允许跨域访问的源
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 允许的请求方法
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 允许的请求头字段
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        // 是否允许发送 Cookie
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true; // 继续执行后续拦截器或目标方法
    }

    /**
     * 该方法在Controller方法执行之后、视图渲染之前调用
     * 可用于对ModelAndView对象进行处理或添加公共数据到模型中
     *
     * @param request      当前HTTP请求
     * @param response     当前HTTP响应
     * @param handler      开始异步执行的处理器(或{@link HandlerMethod}),用于类型和/或实例检查
     * @param modelAndView 处理器返回的{@code ModelAndView}对象(也可以为{@code null})
     * @throws Exception 方法执行异常抛出
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 该方法在整个请求完成(视图渲染结束)后调用,无论是否发生异常
     * 适合用于资源清理、性能监控、事务回滚或日志记录等操作
     * 示例:释放ThreadLocal中存储的用户信息以避免内存泄漏
     *
     * @param request  当前HTTP请求
     * @param response 当前HTTP响应
     * @param handler  开始异步执行的处理器(或{@link HandlerMethod}),用于类型和/或实例检查
     * @param ex       处理器执行过程中抛出的任何异常(如果有的话);这不包括通过异常解析器处理过的异常
     * @throws Exception 方法执行异常抛出
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

实现了HandlerInterceptor接口以后,还需要在WebMvcConfigurer的实现类中添加拦截器使其生效。

/**
 * 在配置类中注册刚才实现的拦截器,使其生效
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    /**
     * 全局配置拦截器
     *
     * @param registry 拦截器集合
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WebInterceptor()) //  添加拦截器
                .addPathPatterns("/**") //  添加拦截路径
                .excludePathPatterns("/api/**");// 排除拦截路径
    }
}
方式四:直接在WebMvcConfigurer实现类中直接配置

/**
 * 直接在配置类中配置跨域
 */
public class WebMvcConfig2 implements WebMvcConfigurer {
    /**
     * 配置跨域
     * @param registry 跨域注册
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允许所有路径跨域
                .allowedOrigins("*") // 允许所有来源
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法
                .allowedHeaders("*") // 允许所有请求头
                .exposedHeaders("X-Custom-Header") // 暴露给浏览器的响应头
                .maxAge(3600) // 预检请求的有效期(秒)
                .allowCredentials(false); // 不允许携带凭证
    }
}

目录

方式一:通过@CrossOrigin注解方式解决跨域问题

方式二:过滤器实现跨域问题

方式三:拦截器解决跨域问题

方式四:直接在WebMvcConfigurer实现类中直接配置


结语:如果还有其他方式,欢迎评论区讨论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值