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 周内。
我正在尝试使用以下代码从我的 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 周内。