对启用 CORS 的 spring 启动端点的 OPTIONS 请求中的奇怪"Allow"标头



为了测试这一点,可以使用 https://spring.io/guides/gs/rest-service-cors/中的示例代码,而无需更改。

下面是没有任何 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 预检选项请求(这对于 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;如果尝试POST到该URL,则会返回405"不允许的方法"错误)。

更奇怪的是,Access-Control-Allow-Methods正确地只列出了GET.

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

允许

"允许"标头列出了资源支持的方法集。

访问控制-允许-方法

访问控制允许方法响应标头指定在响应预检请求时访问资源时允许的一个或多个方法。

"允许">仅说明 Spring 引导应用程序通常支持哪些方法。而访问控制允许方法会告诉您有权访问哪些方法。

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

如果您转到 请求方法文档 你会发现以下内容:

HTTP 请求方法的 Java 5 枚举。旨在与 RequestMapping.method() 属性的 RequestMapping 注解。 请注意,默认情况下,DispatcherServlet 支持 GET、HEAD、POST、 仅放置、修补和删除。DispatcherServlet 将处理 TRACE 和 具有默认 HttpServlet 行为的选项,除非明确告知 要同时调度这些请求类型,请执行以下操作: 查看 "dispatchOptionsRequest"和"dispatchTraceRequest"属性, 如有必要,将它们切换为"true"。

所以默认情况下,@RequestMapping将允许[GET, HEAD, POST, PUT, PATCH , DELETE] 如果要将某些资源或方法限制为可以使用的特定方法

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

最新更新