Flurl PostUrlEncoded 执行 GET 而不是 POST
Flurl PostUrlEncoded does GET instead of POST
我一定是遗漏了一些非常明显的东西,但我说不出是什么。我有一个 DoLoginAsync
像这样:
private async Task DoLoginAsync(bool force = false)
{
try
{
if (client.Cookies.ContainsKey("user_credentials") && !force)
{
return;
}
var html = client.Request("login").GetStringAsync().Result;
var doc = new HtmlDocument();
doc.LoadHtml(html);
var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
var values = new Dictionary<string, string>
{
{ "user_session[email]", user },
{ "user_session[password]", password },
{ "authenticity_token", csrf_token }
};
var result = await client.Request("user_session").PostUrlEncodedAsync(values);
}
catch (Exception e)
{
}
当我 运行 在 catch 子句中带有断点的测试中使用此代码时,我得到一个异常
Call failed with status code 404 (Not Found): GET http://www.whatever.com/user_session
卧槽?我希望 PostUrlEncodedAsync
执行 POST,而不是 GET。有人知道为什么会发生这种情况吗?
Flurl 客户端实例化为client = new FlurlClient(BASE_URL).EnableCookies();
更新
尝试了以下测试,但由于相同的异常而失败
[TestMethod]
public async Task TheTest()
{
var message = "";
try
{
var client = new FlurlClient("http://www.slimmemeterportal.nl/").EnableCookies();
var html = await client.Request("login").GetStringAsync();
var doc = new HtmlDocument();
doc.LoadHtml(html);
var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
var values = new Dictionary<string, string>
{
{ "user_session[email]", "******" },
{ "user_session[password]", "******" },
{ "commit", "inloggen" }, // Not sure if this is actually needed, but it is in the website's request parameters.
{ "authenticity_token", csrf_token }
};
var result = await client.Request("user_session").PostUrlEncodedAsync(values);
}
catch (FlurlHttpException ex)
{
message = ex.Message;
}
Assert.AreEqual("Call failed with status code 404 (Not Found): POST http://www.slimmemeterportal.nl/user_session", message);
}
谜团解开了:在使用 Wireshark 进行一些调试后,网站返回 HTTP 状态代码 301。如前所述 here 默认操作是遵循响应位置中的 URI header 使用 GET,即使原始请求是 POST.
我一定是遗漏了一些非常明显的东西,但我说不出是什么。我有一个 DoLoginAsync
像这样:
private async Task DoLoginAsync(bool force = false)
{
try
{
if (client.Cookies.ContainsKey("user_credentials") && !force)
{
return;
}
var html = client.Request("login").GetStringAsync().Result;
var doc = new HtmlDocument();
doc.LoadHtml(html);
var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
var values = new Dictionary<string, string>
{
{ "user_session[email]", user },
{ "user_session[password]", password },
{ "authenticity_token", csrf_token }
};
var result = await client.Request("user_session").PostUrlEncodedAsync(values);
}
catch (Exception e)
{
}
当我 运行 在 catch 子句中带有断点的测试中使用此代码时,我得到一个异常
Call failed with status code 404 (Not Found): GET http://www.whatever.com/user_session
卧槽?我希望 PostUrlEncodedAsync
执行 POST,而不是 GET。有人知道为什么会发生这种情况吗?
Flurl 客户端实例化为client = new FlurlClient(BASE_URL).EnableCookies();
更新
尝试了以下测试,但由于相同的异常而失败
[TestMethod]
public async Task TheTest()
{
var message = "";
try
{
var client = new FlurlClient("http://www.slimmemeterportal.nl/").EnableCookies();
var html = await client.Request("login").GetStringAsync();
var doc = new HtmlDocument();
doc.LoadHtml(html);
var csrf_token = doc.DocumentNode.SelectNodes("//meta[@name='csrf-token']").First().GetAttributeValue("content", string.Empty);
var values = new Dictionary<string, string>
{
{ "user_session[email]", "******" },
{ "user_session[password]", "******" },
{ "commit", "inloggen" }, // Not sure if this is actually needed, but it is in the website's request parameters.
{ "authenticity_token", csrf_token }
};
var result = await client.Request("user_session").PostUrlEncodedAsync(values);
}
catch (FlurlHttpException ex)
{
message = ex.Message;
}
Assert.AreEqual("Call failed with status code 404 (Not Found): POST http://www.slimmemeterportal.nl/user_session", message);
}
谜团解开了:在使用 Wireshark 进行一些调试后,网站返回 HTTP 状态代码 301。如前所述 here 默认操作是遵循响应位置中的 URI header 使用 GET,即使原始请求是 POST.