跨域问题每个人都会遇到,特别是在前后端分离的系统中。
如果你正在使用 Spring Boot 开发后端应用,并且浏览器中遇到了跨域问题。类似于如下:
Access to fetch at 'http://127.0.0.1/demo' from origin 'https://springdoc.cn' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
但是你又不想去了解跨域、CORS 这些到底是个啥,你只想快速地解决这个问题。
那你可以把如下配置类,添加到你的 Spring Boot 应用中,它可以解决 99% 以上的跨域问题:
// TODO package 声明
import java.time.Duration;
import java.util.Arrays;
import java.util.stream.Stream;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.filter.CorsFilter;
/**
*
- 全局跨域配置
*/
@Configuration
public class CorsFilterConfiguration {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
    CorsFilter corsFilter = new CorsFilter(request -> {
    String origin = request.getHeader(HttpHeaders.ORIGIN);
    if (!StringUtils.hasText(origin)) {
        // 非跨域请求
        return null;
    }
    CorsConfiguration config = new CorsConfiguration();
    // 允许所有域
    config.addAllowedOrigin(origin);
    // 允许所有请求 Header
    String requestHeders = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
    if (StringUtils.hasText(requestHeders)) {
        config.setAllowedHeaders(Stream.of(requestHeders.split(&quot;,&quot;)).map(String::trim).distinct().toList());
    }
    
    // 默认允许 Javascript 访问的响应头
    config.setExposedHeaders(Arrays.asList(&quot;Cache-Control&quot;, &quot;Content-Language&quot;, &quot;Content-Length&quot;, 
            &quot;Content-Type&quot;, &quot;Expires&quot;, &quot;Last-Modified&quot;, &quot;Pragma&quot;));
    
    // 允许携带凭证
    config.setAllowCredentials(true);
    
    // 允许所有请求方法
    config.setAllowedMethods(Arrays.asList(&quot;GET&quot;, &quot;HEAD&quot;, &quot;POST&quot;, &quot;PUT&quot;, 
            &quot;PATCH&quot;, &quot;DELETE&quot;, &quot;OPTIONS&quot;, &quot;TRACE&quot;));
    
    // 预检缓存 30 分钟
    config.setMaxAge(Duration.ofMinutes(30));
    return config;
});
FilterRegistrationBean&lt;CorsFilter&gt; registrationBean = new FilterRegistrationBean&lt;&gt;(corsFilter);
registrationBean.addUrlPatterns(&quot;/*&quot;); // 拦截所有请求
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); // 最先执行
return registrationBean;
}
}
简单说几个要点。
如果你使用这个配置类,那么就没必要使用 Spring / Spring Security 提供的其他跨域解决方案了,例如:WebMvcConfigurer 接口的 addCorsMappings 配置方法、@CrossOrigin 注解。
该配置类,第一行没有 package 声明,你要自己添加。它应该在你的 @SpringBootApplication 子包下,以便被 Spring Boot 自动扫描加载。
如,放到 cn.springdoc.demo.config 包下:
src/main/java
|-cn.springdoc.demo.config
    |-CorsFilterConfiguration.java
|-cn.springdoc.demo
    |-DemoAppplication.java // @SpringBootApplication 类
注意 :代码中的 config.setExposedHeaders(...) 方法,设置了允许被 Javascript 访问的响应头。如果你响应了额外的 Header,且需要被客户端访问。那么需要手动添加。
例如:你的登录接口在登录成功后会响应包含了 Token 的 Header:X-Auth-Token,客户端需要访问这个 Header 来读取、保存 Token。你可以在新的一行中使用 addExposedHeader 方法添加:
config.addExposedHeader("X-Auth-Token");
最后,如果你有兴趣了解一下关于 CORS 跨域的详细信息,推荐阅读《Spring 和 CORS 跨域》。
 51工具盒子
51工具盒子 
                 
                             
                        