OPTIONS请求中奇怪的“允许”标头发送给启用了CORS的Spring Boot端点

时间:2019-07-24 16:53:05

标签: java spring-boot

要对此进行测试,可以直接使用https://spring.io/guides/gs/rest-service-cors/中的示例代码。

这是来自OPTIONS请求的输出,没有任何CORS标头:

$ curl -X OPTIONS -i http://localhost:8080/greeting                                                                                                              HTTP/1.1 200 
Allow: GET,HEAD,OPTIONS
Content-Length: 0
Date: Wed, 24 Jul 2019 16:45:25 GMT

正如预期的那样,Allow标头是正确的,因为该方法用@GetMapping注释。

但是现在让我们模拟一个CORS预检OPTIONS请求(对于GET来说并不是必须的,但这不是重点),添加OriginAccess-Control-Request-Method

$ curl -X OPTIONS -H'Origin: http://localhost:9000' -H'Access-Control-Request-Method: GET' -i http://localhost:8080/greeting
HTTP/1.1 200 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 1800
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
Content-Length: 0
Date: Wed, 24 Jul 2019 16:48:36 GMT

已正确包含CORS标头,但请注意,Allow现在列出了比实际允许的方法更多的方法(有或没有CORS的情况下,实际上都是不允许的;如果出现以下错误,将返回405“ Method not allowed”错误)一个尝试发布到该URL)。

更奇怪的是,Access-Control-Allow-Methods仅列出了GET

我是否误解了一些有关CORS应该如何工作的细节,或者这是Spring Boot中的错误?

2 个答案:

答案 0 :(得分:0)

Allow

  

Allow标头列出了资源支持的方法集。

Access-Control-Allow-Methods

  

Access-Control-Allow-Methods响应标头指定响应预检请求而访问资源时允许使用的一种或多种方法。

允许仅说明了Spring Boot应用程序通常支持的方法。 Access-Control-Allow-Methods 会告诉您可以访问哪些方法。

答案 1 :(得分:0)

如@Thomas所述,allow是一个资源响应标头 因此,如果您仔细查看@RequestMapping属性,您会看到method : RequestMethod[] https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#method--

如果转到RequestMethod文档,则会发现以下内容:

  

Java 5 HTTP请求方法的枚举。旨在与   RequestMapping批注的RequestMapping.method()属性。   请注意,默认情况下,DispatcherServlet支持GET,HEAD,POST,   仅PUT,PATCH和DELETE。 DispatcherServlet将处理TRACE和   具有默认HttpServlet行为的选项,除非明确告知   也可以分派这些请求类型:   “ dispatchOptionsRequest”和“ dispatchTraceRequest”属性,   如有必要,将它们切换为“ true”。

因此,默认情况下,@RequestMapping将允许[GET,HEAD,POST,PUT,PATCH和DELETE] 如果您想限制某些资源或方法用于特定方法,可以使用

@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})