Spring Data REST CORS - 如何处理预检请求(preflight OPTIONS request)?

3
我正在使用Spring Data REST构建RESTful API。到目前为止,我的HTML GUI是从同一Tomcat服务器提供的,对于跨域请求没有任何问题。
现在我想要从另一台服务器提供静态文件。这意味着API位于另一个域/端口上。浏览器将发送OPTIONS请求以从服务器获取Access-Control头信息。不幸的是,Spring Data REST不能处理这些OPTIONS请求,甚至返回HTTP 500错误。
我尝试创建一个自定义控制器来处理所有OPTIONS请求。
@Controller
@RequestMapping(value = "/**", method = RequestMethod.OPTIONS)
public class OptionsController {

    @RequestMapping
    public ResponseEntity options() {
        return new ResponseEntity<Void>(HttpStatus.OK);
    }
}

这适用于OPTIONS请求,但随后所有其他请求(如GET)都无法工作。

可以通过dispatchOptionsRequest调度器servlet参数打开OPTIONS请求。


你尝试过Tomcat的CORS过滤器吗? - Neil McGuigan
不,这个问题在下一个版本的SDR中已经被修复了。我们只是使用了反向代理将请求映射到相同的域和端口。 - FrontierPsychiatrist
2个回答

0

简而言之:目前Spring Data REST根本不会响应OPTIONS请求。

值得在我们的JIRA中开一个工单。

浏览器将发送OPTIONS请求以从服务器获取访问控制标头。

这个规范有具体说明吗?如果有的话,如果工单描述中包含该规范的链接,那就太好了。

关于你的解决方法,有几点评论:

  1. @RequestMapping在控制器方法上覆盖了method属性,并且现在匹配所有HTTP方法,这就是为什么你看到所有请求都被拦截的原因。因此,您也需要在那里定义OPTIONS作为HTTP方法(或者可能是类映射中的替代方法)。
  2. 您没有返回任何Allow标头,这正是OPTIONS的全部目的。
  3. 我想知道这种方法是否有意义,因为很难推断出支持的HTTP方法。

谢谢您的回答! 我尝试了1),本应该发布。但是没有起作用。一旦我注册我的控制器,就不会导出REST数据方法。 标题添加在过滤器中。第3点,我认为CORS是一个常见问题,应该得到支持,特别是对于REST API。 - FrontierPsychiatrist
2
我打开了https://jira.spring.io/browse/DATAREST-333。其中包括对w3c和mozilla的引用。 - FrontierPsychiatrist
@OliverGierke 我注意到Spring Data REST使用org.springframework.http.HttpHeaders.ALLOW设置允许方法头,该头部设置为“Allow”。根据这个W3C建议,头部名称应该是Access-Control-Allow-Methods。为什么会有这种差异? - dimi
我们目前只是按照规范实现了HTTP OPTIONS方法。 - Oliver Drotbohm

0
只需将参数dispatchOptionsRequest设置为true,并将其传递给调度程序以处理Options方法调用,然后实现WebApplicationInitializer即可。
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(applicationContext));

dispatcher.setInitParameter("dispatchOptionsRequest", "true");                

dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接