Swagger TypeError:无法在“Window”上执行“fetch”:使用 GET/HEAD 方法的请求不能有正文

Posted

技术标签:

【中文标题】Swagger TypeError:无法在“Window”上执行“fetch”:使用 GET/HEAD 方法的请求不能有正文【英文标题】:Swagger TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body 【发布时间】:2018-07-22 18:53:13 【问题描述】:

我已将 Swagger 添加到我的 Spring Boot 2 应用程序中:

这是我的 Swagger 配置:

@Configuration
@EnableSwagger2
public class SwaggerConfig 

    @Bean
    public Docket api() 
        // @formatter:off
        return new Docket(DocumentationType.SWAGGER_2)  
                .select()                                  
                .apis(RequestHandlerSelectors.any())              
                .paths(PathSelectors.any())                          
                .build();
        // @formatter:on
    

这是 Maven 依赖项:

<!-- Swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

当我尝试调用例如 http://localhost:8080/api/actuator/auditevents 时,它会失败并出现以下错误:

TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

我做错了什么以及如何解决?

【问题讨论】:

你修好了吗? 有什么解决办法吗? 有什么消息吗? 这是known bug。很高兴有人发布了解决方法in the ticket comments。 【参考方案1】:

错误消息实际上说明了问题所在。在尝试使用 GET 时,您使用 -d 选项通过 curl 发布数据。

如果您使用 -d 选项 curl 将执行POST。 如果你使用 -X GET 选项 curl 会做GET。

HTTP GET 方法用于请求指定资源的表示。使用 GET 的请求只能检索数据,因此不能有正文。

更多信息GET vs POST

【讨论】:

感谢您的回答。我没有直接使用 curl。这是 Swagger 2.8.0 的一些内部输出。顺便说一句 - 我已将 Swagger 版本降级为 2.7.0,问题就消失了。 Swagger 2.8.0 可能有什么问题? 我明白了,也许this 是 Swagger 的问题? 但他使用的是 swagger ui,而不是 curl @Boris 在您提供的链接中,并没有说不可能同时使用 GET 和 body 。 Http 规范允许这样做,因此本主题是关于 swagger 问题(swagger 没有正确实现 http) @Boris 我不同意你的回答。因为curl -d 也称为--data 标志不在乎,是的,您可以将数据传递给它,是的,即使在GET 请求上它也可以工作,例如:curl -X GET "https://veggies.com/carrots" -H "Content-Type: application/json" -d "\"bunny_id\": 22 "。非常适合我,因为 API 支持它,curl 也支持!现在对于它是否普遍或我们是否应该这样做的问题是另一回事。 curl 在任何情况下都没有问题。我尝试过这个。所以问题一定是swagger的fetch函数/方法不是curl -d【参考方案2】:

我遇到了这个问题。以下是我的解决方法:

我有一个这样的方法:

[HttpGet]
public IEnumerable<MyObject> Get(MyObject dto)

      ...

我得到了错误。我相信 swagger UI 将 Get 参数解释为 FromBody,因此它使用 curl -d 标志。我添加了 [FromQuery] 装饰器,问题得到解决:

[HttpGet]
public IEnumerable<MyObject> Get([FromQuery]MyObject dto)

      ...

仅供参考,这也会改变该方法的 UI 体验。而不是提供 json,您将为参数对象的每个属性提供一个表单字段。

【讨论】:

完美答案!【参考方案3】:

我的 .net core 2.0 解决方案和将元素 id 作为标题键或通过正文中的参数搜索它的 GET 方法遇到了同样的问题。这不是最好的实现方式,但它是一种特殊情况。

如this 讨论中所述。 HTTP 规范不禁止在 GET 上使用 body,但 swagger 并没有像这样实现它。即使在 GET 请求中存在与 body 配合良好的 API。

更重要的是,即使它是 null/undefined/empty 对象,swagger 前端也会将此 body 对象添加到请求中。它是 -d "body_content_here" 参数。所以在我的情况下,当我只按 id 搜索并且正文为空时,它仍然发送空对象(-d“”)并抛出提到的错误。

可能的解决方案:

开始为此请求使用邮递员应用程序 - 它会正常工作。经过测试。

考虑将更高级的 GET 请求(如使用条件搜索)移至独立的 POST 方法

使用swagger生成的不带-d参数的CURL请求请求

【讨论】:

CURL 在使用 7.68 版 Ubuntu 上测试的 -d 参数时可以正常工作。真的是 Swagger 不支持带 body 的 GET 请求。【参考方案4】:

不要在 Get 方法中传递方法类型。

let res = await fetch("http://localhost:8080/employee_async",
                method: "POST",
                body:JSON.stringify(data),
                mode:"cors",
                headers: "Content-type":"application/json;charset=utf-8")

这仅用于发布,如果我们不分配任何方法类型节点自动视为Get方法

【讨论】:

欢迎来到 ***。尝试按照here 的描述正确格式化您的代码【参考方案5】:

查看 swagger 异常/错误消息,看起来您正在使用一组输入正文调用 Get 方法。根据 GET 方法的文档不接受任何正文。您需要将 GET 方法更改为 POST 方法。它应该可以工作。

【讨论】:

请提供您阅读该文章的来源的链接。因为实际上official specification允许GET方法有body。【参考方案6】:

为避免此错误,请务必使用 @RequestParam 注释控制器中的参数,例如

@GetMapping("/get")
public Response getData(@RequestParam String param)

【讨论】:

【参考方案7】:

在方法输入中使用 [FromQuery] 传递参数

【讨论】:

点评来源: 嗨,这篇文章似乎没有为问题提供quality answer。请编辑您的答案并改进它,或者将其作为对问题/其他答案的评论发布。 我确认这可行......但是,如果可能的话,我希望能够在 GET 请求中使用正文。【参考方案8】:

可能问题出在方法的映射上,请务必使用 @RequestMapping(value = "/<your path>" , method = RequestMethod.POST) 并将数据作为正文与@RequestBody

【讨论】:

【参考方案9】:

我在 Swagger UI 上也遇到了同样的错误。我的问题是我错误地将 Api 方法标记为 GET 并在请求正文中发送数据。一旦我将注释 @GET 更改为 @POST 问题就解决了。

【讨论】:

【参考方案10】:

因为你使用了 GET http 方法和 body。 如果你想拥有 Json 身体等,你需要使用 POST http 方法, 例如,在您的控制器类中,您的方法的顶部:

    @PostMapping(value = "/save")
    public ResponseEntity<HttpStatus> savePerson(@RequestBody Person person) 
    ...

使用没有正文的 GET。

【讨论】:

【参考方案11】:

我在尝试在 Ruby On Rails 应用上使用 Swagger UI 时遇到了这个问题。我通过更改 curl 命令上的信息容器来修复它。这是一个示例行:

parameter name: :body, in: :body, schema: '$ref' => '#/definitions/ActivitiesFilter', required: true

进入

parameter name: :attribute_name1, in: :query, required: true
parameter name: :attribute_name2, in: :query, required: true
parameter name: :attribute_name3, in: :query, required: true

请注意,您必须添加与swagger_helper 内架构中定义的属性一样多的行

【讨论】:

以上是关于Swagger TypeError:无法在“Window”上执行“fetch”:使用 GET/HEAD 方法的请求不能有正文的主要内容,如果未能解决你的问题,请参考以下文章

Nestjs Swagger UnhandledPromiseRejectionWarning:TypeError:无法解构“未定义”或“空”的属性“原型”

解决django配置swagger后,打开docs报错TypeError:Excepted a ‘coreapi.Document’ instance

swagger : 无法加载 API 定义 undefined /swagger/v1/swagger.json

使用play-swagger存储库无法在localhost中看到swagger json

swagger 无法访问 OAuth2

Spring+Swagger文档无法排序问题解决