覆盖SpringBoot中的默认OPTIONS方法

时间:2018-01-03 11:52:50

标签: ajax spring spring-boot spring-restcontroller

我有一个休息控制器(SPRINGBOOT),实现了自定义'OPTIONS'方法。 问题是:当我对这个'OPTIONS'方法进行ajax调用时,我默认获得两个响应,另一个来自实现的响应。第二个回应来自哪里。如果是来自SPRINGBOOT中'OPTIONS'方法的默认处理,如何禁用它?

My Rest Controller看起来像这样:

@RestController
public class FetchOnPremData {

    @RequestMapping(value = "/fetchData/{jiraid}", method = RequestMethod.OPTIONS)
    public int options(@PathVariable String jiraid ,HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Methods","GET,HEAD,POST");
        response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
        response.setHeader("Access-Control-Allow-Origin","*");
        return 234;
    }
}

我做的AJAX调用如下:

   $.ajax({

    type: 'OPTIONS',
    context: this,
      url: "https://myserverurl/fetchData/CFNDGEMINI-128",
      success: function(oResponseStatus, xhr) 
    {if (oResponseStatus === 234) {
console.log("valid");}
     else {
    console.log("invalid");                                                                                   
    }

编辑: How to handle HTTP OPTIONS requests in Spring Boot?

这个问题解决了OPTIONS方法没有被调用的问题。在我的情况下,OPTIONS方法正在工作,但另一个OPTIONS方法也给出了响应。我的问题是询问其他回复的来源。

1 个答案:

答案 0 :(得分:1)

默认情况下,您的浏览器必须首先生成第一个请求作为CORS的合同。由于存在预检标题,Spring的CORS Processor解决了此请求。

如果Spring通过发送正确的Headers来允许它,那么浏览器将生成您的实际请求,这将由您的其他控制器解决。 现在,如果您仍想自己处理预检请求,则必须扩展CORSConfiguration类并覆盖其方法。

注意: - 即使您这样做,您的浏览器也会提出两个请求。 首先是您的自定义覆盖方法,其次是您的控制器。 通常,不需要为OPTIONS定义控制器,因为您的应用程序中不需要OPTIONS请求。如果需要[根据CORS合同] ,由浏览器自动引发,它将由spring CORS Processor处理。

配置CORS(如果您不使用Spring-security模块):  
有三种方式

  1. 使用注释@Crossorigin [per rest-api或per rest controller 基础]

  2. 使用全局CORS配置

  3. 扩展CorsFilter

  4. 方式1(@CrossOrigin) 此批注可以应用于类或方法。 例如: -

    @RestController
    @CrossOrigin(origins = {"http://localhost:8585"}, maxAge = 4800, allowCredentials = "false")
    public class FetchOnPremData {
    
        @RequestMapping(value = "/fetchData/{jiraid}", method = RequestMethod.OPTIONS)
        public int options(@PathVariable String jiraid ,HttpServletResponse response) {
            response.setHeader("Access-Control-Allow-Methods","GET,HEAD,POST");
            response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
            response.setHeader("Access-Control-Allow-Origin","*");
            return 234;
        }
    }
    

    或方法:

    @RestController
    public class FetchOnPremData {
    
        @CrossOrigin
        @RequestMapping(value = "/fetchData/{jiraid}", method = RequestMethod.GET)
        public int options(@PathVariable String jiraid ,HttpServletResponse response) {
    // your code
            return 234;
        }
    

    方式2:全球Cors配置 如果要为所有其他控制器启用cors支持,请使用此选项。

    @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
                .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(false).maxAge(3600);
        }
    }
    

    方式3:使用CorsFilter

    如果你想要更好的控制,你可以更喜欢这个。

        @Configuration
        @EnableWebMvc
        public class WebConfig extends WebMvcConfigurerAdapter {
    
    
        // This bean will override default cors filter 
        @Bean
        CorsConfigurationSource corsConfigurationSource() {
            CorsConfiguration configuration = new CorsConfiguration();
            configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
            configuration.setAllowedMethods(Arrays.asList("GET","POST"));
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", configuration);
            return source;
        }
    }
    

    配置CORS(如果您使用的是Spring-Security模块):

    然后,除了使用上述任何方法之外,您还必须在配置中添加以下内容:

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                // by default uses a Bean by the name of corsConfigurationSource
                .cors().and()
                ...
        }
    }
    

    参考:
    Spring Security CORS Configuration documentation
    Spring MVC CORS Configuration documentation