【问题标题】:Overriding default OPTIONS method in SpringBoot在 Spring Boot 中覆盖默认的 OPTIONS 方法
【发布时间】:2018-06-13 02:20:19
【问题描述】:

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

我的 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 方法也在给出响应。我的问题是询问其他响应来自哪里。

【问题讨论】:

标签: ajax spring spring-boot spring-restcontroller


【解决方案1】:

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

如果 Spring 通过发送适当的标头允许它,那么浏览器将生成您的实际请求,该请求将由您的休息控制器处理。 现在,如果您仍想自己处理预检请求,则必须扩展 CORSConfiguration 类并覆盖其方法。

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

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

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

  2. 使用全局 CORS 配置

  3. 扩展 CorsFilter

方式 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 配置 如果你想为你所有的 rest 控制器启用 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

【讨论】:

  • 这听起来不错,所以我应该扩展 fetchonpremdata 类对吗?
  • 我已在答案中添加了详细信息。看看吧
  • 嘿,这似乎并没有覆盖默认的 cors 支持。我已经检查了所有可能性,但仍然默认的 springboot 选项方法正在响应。请同时检查此链接。 github.com/spring-projects/spring-boot/issues/5834
  • 你用的是什么版本的spring?
  • 我使用的是 springboot 1.5.8。发布
猜你喜欢
  • 2019-05-15
  • 2016-08-20
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 2015-08-30
  • 2015-06-22
  • 1970-01-01
相关资源
最近更新 更多