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

106

我已经将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.

这里输入图片描述

我做错了什么,该如何解决?


1
你修好了吗? - Kalpesh Soni
1
有没有解决方案? - sebnukem
有关它的任何消息吗? - gstackoverflow
2
这是一个已知的错误。幸运的是,有人在工单评论中发表了解决方法。 - t0r0X
13个回答

54
我遇到了这个问题,以下是我解决的方法:
我有一个像这样的方法:
[HttpGet]
public IEnumerable<MyObject> Get(MyObject dto)
{
      ...
}

我遇到了错误。我认为Swagger UI将Get参数解释为FromBody,因此它使用curl -d标志。我添加了[FromQuery]修饰符,问题得到了解决:

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

顺带提一下,这也会改变该方法的用户界面体验。不再提供json格式,而是为参数对象的每个属性提供一个表单字段。


完美的答案! - Hamit YILDIRIM
这个有效!我不知道为什么楼主没有将其标记为正确答案。 - Najeeb

53

错误信息实际上表明了问题所在。您使用 curl-d 选项发布数据,同时尝试使用 GET.

如果您使用 -d 选项,curl 将执行 POST 方法。
如果您使用 -X GET 选项,curl 将执行 GET 方法。

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

有关更多信息,请参见GET vs POST


13
谢谢你的回答。我并没有直接使用curl。这是Swagger 2.8.0的一些内部输出。顺便说一下,我已经将Swagger版本降级为2.7.0,问题已经解决了。Swagger 2.8.0可能出了什么问题? - alexanoid
3
我了解了,也许这就是Swagger的问题吗?链接在此:https://github.com/springfox/springfox/issues/1781 - Boris
7
他正在使用Swagger UI,而不是Curl。 - Kalpesh Soni
6
在你提供的链接中,并没有说不能同时使用GET和消息体(body)的方法。HTTP规范允许这样做,因此这个问题与Swagger有关(Swagger没有正确实现HTTP)。 - Evgeny Gorbovoy
8
我不同意你的答案,因为 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 - Khalil Gharbaoui
显示剩余8条评论

10

我的.NET Core 2.0解决方案与GET方法存在同样的问题,它使用元素ID作为标题键或在请求体参数中搜索。这不是最好的实现方式,但这是一种特殊情况。

正如讨论中所提到的,HTTP规范并不禁止在GET请求中使用请求体,但swagger没有像这样实现。即使有一些API能够正常使用GET请求的请求体。

更重要的是,Swagger前端即使对象为空(null/undefined/empty object),也会将该对象添加到请求中。它是“-d”“body_content_here”的参数。因此,在我的情况下,当我只是按ID搜索时,请求体为空,它仍然发送空对象(“-d”“{}”)并抛出了上述错误。

可能的解决方法:

  • 使用Postman应用程序进行此请求-它将正常工作。已测试。

  • 考虑将更高级的GET请求(例如带有标准的搜索)移动到独立的POST方法中

  • 使用由Swagger生成的CURL请求而不带“-d”参数


1
当在Ubuntu上测试版本7.68时,使用-d参数的CURL工作正常。真正不支持带有请求体的GET请求是Swagger。 - Slobodan Savkovic

5
为避免此错误,请确保在控制器中使用@RequestParam注释参数,例如:
@GetMapping("/get")
public Response getData(@RequestParam String param)

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"}})

这仅用于提交(post),如果我们没有指定任何方法类型,节点会自动被视为Get方法


3
欢迎来到 Stackoverflow。请按照这里所述的方式正确格式化您的代码。 - Felipe Augusto

2

看起来你正在使用Swagger时遇到了异常/错误信息,这似乎是因为你在使用带有一组输入内容的GET方法。根据GET方法的文档,它不接受任何请求体。你需要将GET方法更改为POST方法,这样应该可以解决问题。


12
请提供您阅读该信息的来源链接。实际上,官方规范允许GET方法具有消息主体。 - denisq
POST 用于在现有实体集中创建新实体... 当使用查询字符串时,接受多个输入条件的 GET 方法可能会出现问题,当与输入相关联的文本超过 URL 限制时。 - NitinSingh
@kris,你能提供这个信息的来源或者纠正一下吗? - Benni

0

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


0

这个错误是由于参数类型不正确引起的。只需将“[FromBody]”更改为“[FromQuery]”即可。


0

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


2
来自评论:嗨,这篇帖子似乎没有为问题提供高质量答案。请编辑您的答案并改进它,或将其作为评论发布到问题/其他答案中。 - sɐunıɔןɐqɐp
我确认这个能用... 但是,如果可能的话,我想在Swagger中使用GET请求的主体。 - max

0
也许问题出在方法的映射上,请确保使用以下代码:
@RequestMapping(value = "/", method = RequestMethod.POST)
并将数据作为请求体(body)放置,使用 @RequestBody。

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