springboot前後端分離跨域同源問題
阿新 • • 發佈:2018-12-17
筆者最近做springboot前後端分離遇到一些問題,在這裡分享下。主要是跨域問題,導致後端無法獲取自定義請求頭,
前端後臺分開部署在不同域名,自然而然就會存在跨域問題,前端ajax的處理方式通常就是jsonp。
springboot 後端配置有如下兩種方式,二選一就好
1、
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { /** * 增加對跨域對支援 * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**")// 這是請求對映路徑 .allowedHeaders("*")// 這裡是所有請求頭的意思 .allowedOrigins("*")// 允許任何源反問(不安全),這裡一般填前端域名 .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .maxAge(3600) .allowCredentials(true); } }
2、
@Component public class CustomCorsFilter extends CorsFilter { public CustomCorsFilter() { super(configurationSource()); } private static UrlBasedCorsConfigurationSource configurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.setMaxAge(36000L); config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } }
配置完以上資訊之後跟前端除錯,登入請求就無法進入到指定方法。已經在攔截器被攔截。一直很鬱悶。前端debbug模式返回如下:
一直以為是前端的問題。後面才知道是瀏覽器跨域同源問題,瀏覽器會先發送一個options的預請求,當後端返回攔截返回true,瀏覽器才回發起真正的請求,後端攔截器配置如下:
public class RestApiInteceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof org.springframework.web.servlet.resource.ResourceHttpRequestHandler) { return true; } // HandlerMethod handlerMethod = (HandlerMethod) handler; return check(request, response, null); } private boolean check(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) { if (request.getServletPath().equals(JwtConstants.AUTH_PATH)) { return true; } if("OPTIONS".equals(request.getMethod())){ try{ //預請求需要往回寫 讓ajax預請求知道預請求是成功的 response.setStatus(200); response.getWriter().write(1); return true; }catch (Exception e){ return false; } } return true; }
至此,前後端分離跨域問題才算解決