如何使用 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 文件),如何下载?
发出 JSON RPC API 的 GET 请求而不是 POST 请求