如何使用 LWP 发出 JSON POST 请求?

Posted

技术标签:

【中文标题】如何使用 LWP 发出 JSON POST 请求?【英文标题】:How can I make a JSON POST request with LWP? 【发布时间】:2011-05-11 02:24:24 【问题描述】:

如果您尝试在https://orbit.theplanet.com/Login.aspx?url=/Default.aspx 登录(使用任何用户名/密码组合),您会看到登录凭据作为非传统的 POST 数据集发送:只是一个孤立的 JSON 字符串,没有普通的 key=值对。

具体来说,而不是:

username=foo&password=bar

甚至类似:

json="username":"foo","password":"bar"

很简单:

"username":"foo","password":"bar"

是否可以使用LWP 或替代模块执行此类请求?我准备使用IO::Socket 这样做,但如果可以的话,我更喜欢更高级的东西。

【问题讨论】:

【参考方案1】:

您需要手动构建 HTTP 请求并将其传递给 LWP。应该这样做:

my $uri = 'https://orbit.theplanet.com/Login.aspx?url=/Default.aspx';
my $json = '"username":"foo","password":"bar"';
my $req = HTTP::Request->new( 'POST', $uri );
$req->header( 'Content-Type' => 'application/json' );
$req->content( $json );

然后就可以用LWP执行请求了:

my $lwp = LWP::UserAgent->new;
$lwp->request( $req );

【讨论】:

我的搜索是使用普通的 GET/POST 方法,从 json sn-p 可能不明显,所以我也敢于贡献 GET/POST 用法new HTTP::Request( 'GET' => "http://url/path", ['Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'], 'par1=par1value&par2=par2value' ); 【参考方案2】:

只需创建一个以它为主体的 POST 请求,然后将其提供给 LWP。

my $req = HTTP::Request->new(POST => $url);
$req->content_type('application/json');
$req->content($json);

my $ua = LWP::UserAgent->new; # You might want some options here
my $res = $ua->request($req);
# $res is an HTTP::Response, see the usual LWP docs.

【讨论】:

print $res->decoded_content 应该打印解码后的响应【参考方案3】:

该页面仅使用“匿名”(无名称)输入,恰好是 JSON 格式。

您应该能够使用$ua->post($url, ..., Content => $content),而后者又使用HTTP::Request::Common 中的POST() 函数。

use LWP::UserAgent;

my $url = 'https://orbit.theplanet.com/Login.aspx?url=/Default.aspx';
my $json = '"username": "foo", "password": "bar"';

my $ua = new LWP::UserAgent();
$response = $ua->post($url, Content => $json);

if ( $response->is_success() ) 
    print("SUCCESSFUL LOGIN!\n");

else 
    print("ERROR: " . $response->status_line());

或者,您也可以对 JSON 输入使用哈希:

use JSON::XS qw(encode_json);

...

my %json;
$jsonusername = "foo";
$jsonpassword = "bar";

...

$response = $ua->post($url, Content => encode_json(\%json));

【讨论】:

我相信您缺少“post”功能的内容类型设置 - 我认为 LWP 不会猜到它,它默认为 'x-www-form-urlencoded'【参考方案4】:

如果你真的想使用 WWW::Mechanize 你可以在发布前设置标题'content-type'

$mech->add_header( 
'content-type' => 'application/json'
);

$mech->post($uri, Content => $json);

【讨论】:

以上是关于如何使用 LWP 发出 JSON POST 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 Cloud Scheduler 发出的 HTTP POST 请求上添加 JSON 正文?它会添加“Content-Type”:“application/json”标头吗?

向服务器发出 JSON POST 请求,接收二进制响应(Excel 文件),如何下载?

如何使用 OKHTTP 发出 post 请求?

发出 JSON RPC API 的 GET 请求而不是 POST 请求

在 Swift 中使用 JSON 正文发出 HTTP Post 请求

改造:如何发出 XML 请求并取回 JSON 响应