SpringBoot中到底该如何解决跨域问题

  • Post category:http

SpringBoot中,要解决跨域问题,通常有以下三种方法,分别是通过注解、过滤器、Spring Security来实现。

方法一:通过注解解决跨域问题

在SpringBoot中,使用注解方式解决跨域问题,只需在Controller类或方法上添加@CrossOrigin注解即可。

@RestController
public class DemoController {

   @CrossOrigin(origins = "*", maxAge = 3600)
   public String index() {
       return "Hello";
   }
}

上面的代码中,@CrossOrigin注解中的origins = "*"表示允许所有来源的请求访问,maxAge = 3600表示使用缓存时间,单位是秒。

方法二:通过过滤器解决跨域问题

在SpringBoot中,可以通过编写自定义的过滤器来解决跨域问题。主要思路是在过滤器中添加响应头信息,以允许跨域访问。

@Component
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");
       chain.doFilter(req, res);
   }
}

方法三:通过Spring Security解决跨域问题

在SpringBoot中,可以通过Spring Security来解决跨域问题。通常需要在WebSecurityConfigurerAdapter的子类中进行相关配置。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.authorizeRequests()
               .antMatchers("/**").permitAll()
               .and().csrf().disable();
       http.headers().frameOptions().disable();
       http.headers().addHeaderWriter(new StaticHeadersWriter(Arrays.asList(
               new Header("Access-control-Allow-Origin", "*"),
               new Header("Access-Control-Expose-Headers", "Authorization"))));
   }
}

上述代码中,http.authorizeRequests().antMatchers("/**").permitAll()表示允许所有请求都访问,同时禁止使用csrf和iframe保护。

以上三种解决跨域问题的方法,各有优缺点,我们需要根据具体需求来选择使用哪一种方法。其中,@CrossOrigin注解方式是最简单的,适合小型项目;自定义过滤器方式适合中大型项目;而使用Spring Security来解决跨域问题,则适合对安全性要求比较高的项目。

示例1:通过注解方式解决跨域问题

添加@CrossOrigin注解:

@RestController
public class UserController {

    @GetMapping("/list")
    @CrossOrigin(origins = "*", maxAge = 3600) // 添加@CrossOrigin注解
    public List<User> listUsers() {
        //...
    }
}

示例2:通过过滤器方式解决跨域问题

自定义CorsFilter类:

@Component
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");
        chain.doFilter(req, res);
    }
}

在过滤器链中添加CorsFilter类:

@Configuration
public class MyFilterConfig {

    @Autowired
    private CorsFilter corsFilter;

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(corsFilter); //添加CorsFilter类
        registration.addUrlPatterns("/*"); //设置过滤器的URL模式
        registration.setName("corsFilter"); //设置过滤器名称
        registration.setOrder(1); //设置执行顺序
        return registration;
    }
}