SpringBoot设置跨域的几种方式
单个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("/**");
}
}