1. 程式人生 > >springboot前後端分離跨域同源問題

springboot前後端分離跨域同源問題

筆者最近做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;
    }

至此,前後端分離跨域問題才算解決