HttpClient post 产生错误的 headers 而没有 body

HttpClient post produces wrong headers and no body

我正在尝试使用以下代码从我的 api 获取数据:

            _httpClient.DefaultRequestHeaders.Accept.Clear();
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var content = new StringContent(JsonConvert.SerializeObject(parameters), UTF8Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync(uri, content);

不幸的是,当我尝试使用 Fiddler 调试此请求时,它会生成此原始请求。

OPTIONS https://localhost:7052/v1/users/login HTTP/1.1
Host: localhost:7052
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: https://localhost:7063
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: https://localhost:7063/
Accept-Encoding: gzip, deflate, br
Accept-Language: pl,en;q=0.9,en-GB;q=0.8,en-US;q=0.7

正确的应该是:

POST https://localhost:7052/v1/users/login HTTP/1.1
Host: localhost:7052
Connection: keep-alive
Content-Length: 50
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="100", "Microsoft Edge";v="100"
accept: application/json
Content-Type: application/json
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44
sec-ch-ua-platform: "Windows"
Origin: https://localhost:7052
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://localhost:7052/swagger/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: pl,en;q=0.9,en-GB;q=0.8,en-US;q=0.7

{
  "username": "string",
  "password": "string"
}

我正在努力解决这个问题,也许我遗漏了一些明显的东西?

编辑: 我的 CORS 配置错误。谢谢 Panagiotis Kanavos 为我指明了正确的方向。

在我的最小 api 项目中,我必须配置 CORS 策略

builder.Services.AddCors(options => options.AddDefaultPolicy(builder =>
builder.AllowAnyOrigin()
       .AllowAnyHeader()
       .AllowAnyMethod()
));

之前

app.UseCors(); 

代理字符串表明您正在使用 Blazor 并向使用 CORS 的站点发送请求。 OPTIONS 请求是 a CORS pre-flight request 并且完全正常。浏览器正在询问服务器是否可以发出 POST 请求。

如果您使用浏览器的开发人员工具,您会在 OPTIONS 请求之后立即看到 POST 请求。

正如文档所解释的:

For some CORS requests, the browser sends an additional request, called a "preflight request", before it sends the actual request for the resource.

The browser can skip the preflight request if the following conditions are true:

  • The request method is GET, HEAD, or POST, and

  • The application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, and

  • The Content-Type header (if set) is one of the following:

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

您正在发送 JSON 字符串,因此无法避免预检请求。

在 .NET 6 中,您可以使用 PostAsJsonAsync 并删除大部分代码,但不包括 OPTIONS 请求。

由于 .NET 6 是当前的 LTS 版本,您迟早应该迁移到它。 .NET 5 goes out of support 在 3 周内。