先说结论,拦截器会让WebMvcConfigurer全局跨域配置失效,这种情况下可以使用过滤器进行跨域处理。

我在写自己的后端接口时使用了下面的代码来解决跨域,不知道为什么没有生效,有趣的是登录并获取token的login接口却跨域生效了,真的让人头大

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedOrigins("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

在此附上我的请求拦截器代码:

@Component
public class RequestContextInterceptor implements HandlerInterceptor {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private LogService logService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logService.insertAccessLog(request);
        String token = request.getHeader("Authorization");
        if(Objects.equals(request.getRequestURI(), "/login")){
            return true;
        }
        if(!TokenUtils.verify(token)){
            postInterceptor(response,"token验证失败的访问");
            return false;
        }
        return true;

    }
    protected void postInterceptor(HttpServletResponse response,String message) throws Exception {
        logger.error(message);
        // 如果被拦截,返回信息
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        ObjectMapper objectMapper = new ObjectMapper();
        response.getWriter().println(objectMapper.writeValueAsString(Response.fail(299, null, "token验证失败")));
        return;
    }
}

能看到因为某些原因拦截器这里是没有对login接口做拦截的,难不成是拦截器与WebMvcConfigurer跨域配置冲突的问题?

果不其然,改为过滤器解决跨域问题之后就解决了,在此附上过滤器跨域代码:

@Component
public class CorsFilter implements Filter {

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        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", "*");

        chain.doFilter(req, res);

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}

结论

在使用拦截器时不能使用WebMvcConfigurer跨域配置,拦截器是会让跨域配置失效(除非这个请求不会被拦截,像我这里的login接口),改为过滤器完美解决

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐