配置WebMvcConfigurer全局跨域,不生效的原因及解决办法

先说结论,拦截器会让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接口),改为过滤器完美解决

WebConfigurer跨域失败的原因是拦截器的存在。拦截器会让WebMvcConfigurer全局跨域配置失效。因此,如果你在WebMvcConfigurer中设置了跨域配置,而同时使用了拦截器,那么跨域配置就不会生效。 为了解决这个问题,可以使用过滤器来进行跨域处理。过滤器不会影响WebMvcConfigurer的全局跨域配置。所以,当需要同时使用拦截器和跨域配置时,可以考虑使用过滤器来处理跨域请求。 另外,如果你在WebMvcConfigurer中设置了跨域配置,但是在WebSecurityConfigurerAdapter中没有设置http.cors(),那么可能会导致一个问题。如果一个需要经过Spring Security过滤器验证的请求没有通过验证,那么该请求将不会交给WebMvcConfigurer的跨域过滤器处理。这会导致响应头中不会携带“Access-Control-Allow-Origin”字段,从而使浏览器认为服务器不接受该地址的跨域请求。为了避免这个问题,需要在WebSecurityConfigurerAdapter和WebMvcConfigurer中同时开启跨域设置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [配置WebMvcConfigurer全局跨域不生效原因解决办法](https://blog.csdn.net/qq_41348755/article/details/124153635)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Springboot跨域失败,配置无效,原因出自SpringSecurity!](https://blog.csdn.net/GD_MRS_LIN/article/details/113573145)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值