Spring MVC CORS不适用于错误控制器

时间:2017-04-09 21:07:54

标签: spring spring-mvc

我将Spring MVC应用程序配置为使用CORS:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**");
}

这适用于成功的请求但是当抛出异常并被我的错误处理程序拾取时,不会添加CORS头。

@ControllerAdvice
public class ApiErrorHandler {

   @ExceptionHandler(value = HttpClientErrorException.class)
   public ResponseEntity badRequest(Exception ex) 
   {
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorBodyWrapper.wrapErrorInJson(ex.getMessage()));
   }
}

有没有理由CORS不能用于错误处理程序?

由于

4 个答案:

答案 0 :(得分:1)

和你一样。

@Configuration
public class ManagerWarInit extends WebMvcConfigurerAdapter {

    ... 

    private static final String[] SUPPORT_METHODS = new String[] {
            HttpMethod.HEAD.name(),
            HttpMethod.OPTIONS.name(),

            HttpMethod.GET.name(),
            HttpMethod.POST.name(),

            HttpMethod.PUT.name(),
            HttpMethod.DELETE.name()
    };
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedMethods(SUPPORT_METHODS)
                .exposedHeaders("Set-Cookie");
    }
}

和globalException

@ControllerAdvice
public class ManagerGlobalException {

    // @CrossOrigin(...)
    @ExceptionHandler(NotLoginException.class)
    public void noLogin(NotLoginException e, HttpServletResponse response)
                       throws IOException {
        if (LOG.isDebugEnabled())
            LOG.debug(e.getMessage());

        if (RequestUtils.isAjaxRequest()) {
            RequestUtils.toJson(notLogin(), response);
        } else {
            response.sendRedirect("hxxp://www.xxx.com");
        }
    }
}

但浏览器(Chrome等)的跨域调用错误

XMLHttpRequest cannot load hxxp://127.0.0.1:8080/url... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'hxxp://127.0.0.1:3000' is therefore not allowed access.

尝试在ExceptionHandler上添加@CrossOrigin注释仍有此错误

我正在处理这个问题

@ControllerAdvice
public class ManagerGlobalException {

    @ExceptionHandler(NotLoginException.class)
    public String notLogin(NotLoginException e) throws IOException {
        if (LOG.isDebugEnabled())
            LOG.debug(e.getMessage());

        if (RequestUtils.isAjaxRequest()) {
            return "forward:/not-login";
        } else {
            return "redirect:hxxp://www.xxx.com";
        }
    }
}

添加映射

@RestController
public class IndexController {

    @RequestMapping(value = "/not-login")
    public JsonResult notLogin() {
        return JsonResult.notLogin();
    }
}

答案 1 :(得分:1)

在mvc中,不是springboot, 一个像垃圾一样的项目,将会杀死我,遇到同样的问题; springmvc.xml用于处理cros,配置如下:

    <mvc:cors>

    <mvc:mapping path="/**"
                 allowed-origins="*"
                 allowed-methods="*"
                 allowed-headers="*"
                 exposed-headers="Access-Control-Allow-Origin,Access-Control-Allow-Credentials"
                 allow-credentials="true"
                 max-age="3600"/>

</mvc:cors>

大多数请求都可以处理,但是@ ControllerAdvice,@ ExceptionHandler无法处理结果为cros的异常,js ajax无法接收结果并使用Cros来抛出异常

我尝试使用servlet过滤器,mvc拦截器,但全部无效

所以我通过@ExceptionHandler做到了这一点

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
    response.setHeader("Access-Control-Allow-Methods", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.getWriter().write(JSONUtil.toJsonString("xxxxxxx error json result"));

它起作用了 也许mvcDispatchServlet忘记为异常响应添加cros标头, 所以我做了 但这还不够优雅

答案 2 :(得分:0)

我认为默认情况下,添加到映射的唯一方法是GET, 在你的&#34; addCorsMappings&#34;尝试指定要将标题添加到

的方法
       registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");

答案 3 :(得分:0)

使用Spring CorsFilter可以解决此问题。

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);

        config.addAllowedOrigin("*");

        config.addAllowedHeader("*");
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));

        bean.setOrder(0);
        return bean;
    }