spring跨域处理
:::warning
注意:使用springsecurity时会出现跨域问题!在websecurityconfig上面加上.cors()方法!!!!!!
:::
https://blog.csdn.net/weixin_45059597/article/details/107490252
使用过滤器
过滤器其实不是spring管理的,而是servelet管理的,常用的GenericFilterBean
,OncePerRequestFilter
,spring管理的Interceptor
第一种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.site.blog.filters;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;
@Configuration public class CorsConfig { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOriginPattern("*" ); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setAllowCredentials(true); return corsConfiguration; }
@Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } }
|
第二种写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @WebFilter(value = "/*") @Component public class CorsFilter extends GenericFilterBean {
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, httpServletRequest.getHeader(HttpHeaders.ORIGIN)); httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Origin, X-Requested-With, Content-Type, Accept"); httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, DELETE, OPTIONS"); httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "3600");
if (!CorsUtils.isPreFlightRequest(httpServletRequest)) { chain.doFilter(httpServletRequest, httpServletResponse); } }
}
|
或者(自己手动写请求头,推荐上面那种)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import org.springframework.context.annotation.Configuration;
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.IOException;
@WebFilter(filterName = "CorsFilter ") @Configuration 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-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); } }
|
也可以使用拦截器:代码如下
:::warning
这里不能使用allowedOriginsPattern(“*”)配置多个
但是可以使用response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin") );
设置动态请求头实现跨域
:::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
@Component public class InterceptorCORS 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", "*"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); if (request.getMethod().equals(HttpMethod.OPTIONS.name())){ response.setStatus(HttpServletResponse.SC_OK); return false; } 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 {
} }
|
然后添加webmvcconfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Configuration public class WebMvcConf implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String filePath =File.separator + "HellohaoData" + File.separator; registry.addResourceHandler("/links/**").addResourceLocations("file:"+filePath);
} @Resource private InterceptorCORS interceptorCORS;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(interceptorCORS).addPathPatterns("/**"); } }
|
官网使用addCorsMapping,但是限制太多,不推荐用
:::warning
注意:addCorsMapping 会被interceptor覆盖,后续如果添加自定义的拦截器(包括Spring security),addCorsMappings方法实现的统一跨域配置就会失效,其原因在于请求经过的先后顺序:
当请求到来时会先进入拦截器中,而不是进入Mapping映射中,所以返回的头信息中并没有配置的跨域信息。浏览器就会报跨域异常
:::
链接
这里可以使用allowedOriginsPattern(“*”)配置多个
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Configuration(proxyBeanMethods = false) public class MyConfiguration implements WebMvcConfigurer {
public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("*") .maxAge(3600); } }; }
|