Win32::IE::Mechanizeを使用します。最近では、すべての Windows システムに何らかのバージョンの Internet Explorer が搭載されています (ただし、システムによっては、管理者が機能をブロックする場合があります)。
Win32::OLEを使用して IE を「手動で」駆動することもできます;-)
次のコードは、古い Windows XP SP3 システムで「動作」します。Vista または Windows 7 UAC で動作するかどうかはわかりません。showcgi.pl
オブジェクトの状態を単にダンプし$cgi
ます。以下の出力を確認できます。
私のブログ投稿で、何が起こっているのかを詳しく説明しています。
テスト用に SSL サーバーをセットアップしていませんが、これらの変更後にスクリプトが機能するかどうか教えてください。
#!/usr/bin/env perl
package My::Poster;
use strict; use warnings;
use Const::Fast;
use Try::Tiny;
use Win32::OLE;
use Win32::OLE::Variant;
local $Win32::OLE::Warn = 3;
# http://msdn.microsoft.com/en-us/library/aa768360%28v=vs.85%29.aspx
const my %BrowserNavConstants => (
navOpenInNewWindow => 0x1,
navNoHistory => 0x2,
navNoReadFromCache => 0x4,
navNoWriteToCache => 0x8,
navAllowAutosearch => 0x10,
navBrowserBar => 0x20,
navHyperlink => 0x40,
navEnforceRestricted => 0x80,
navNewWindowsManaged => 0x0100,
navUntrustedForDownload => 0x0200,
navTrustedForActiveX => 0x0400,
navOpenInNewTab => 0x0800,
navOpenInBackgroundTab => 0x1000,
navKeepWordWheelText => 0x2000,
navVirtualTab => 0x4000,
navBlockRedirectsXDomain => 0x8000,
navOpenNewForegroundTab => 0x10000,
);
sub new {
my $class = shift;
my $self = bless {} => $class;
$self->init;
return $self;
}
sub ie {
my $self = shift;
my $ie = shift;
return $self->{ie} unless defined $ie;
$self->{ie} = $ie;
return;
}
sub init {
my $self = shift;
$self->ie(
Win32::OLE->new(
'InternetExplorer.Application',
sub {
my $ie = shift;
try { $ie->Quit if $ie } catch { warn "$_\n" };
},
)
);
return;
}
sub post {
my $self = shift;
my ($url, $data) = @_;
my $ie = $self->ie;
my $flags = $BrowserNavConstants{navNoHistory} |
$BrowserNavConstants{navNoReadFromCache} |
$BrowserNavConstants{navNoWriteToCache} |
$BrowserNavConstants{navEnforceRestricted} |
$BrowserNavConstants{navNewWindowsManaged} |
$BrowserNavConstants{navUntrustedForDownload} |
$BrowserNavConstants{navBlockRedirectsXDomain}
;
# $postdata should also be converted to bytes here
# I don't remember the right way to do it, and it works for ASCII
# so it should be good enough for now.
my $postdata = join '&', map join('=', @$_), @$data;
my $vPostData = Variant(VT_ARRAY|VT_UI1, length $postdata);
$vPostData->Put($postdata);
# http://msdn.microsoft.com/en-us/library/aa752133%28v=vs.85%29.aspx
$ie->Navigate(
$url,
$flags,
'_self',
$vPostData,
"Content-Type: application/x-www-form-urlencoded\015\012",
);
while ($ie->{ReadyState} != 4) {
sleep 1;
}
return $ie->Document->documentElement->innerHTML;
}
sub DESTROY {
my $self = shift;
try { $self->ie->Quit } catch { warn "$_\n" };
return;
}
package main;
use strict; use warnings;
my $poster = My::Poster->new;
my $html = $poster->post(
'http://test.localdomain:8080/cgi-bin/showcgi.pl',
[
[ thisvar => 'thatvalue', ],
[ anothervar => 'anothervalue', ],
[ oh => 'lala', ],
],
);
print $html if defined $html;
出力:
$VAR1 = 祝福( {
'.parameters' => [
'thisvar',
'別の変数',
'おー'
]、
'.crlf' => '
'、
'.globals' => {
「デバッグ」=> 0、
'NO_UNDEF_PARAMS' => 0,
'NO_NULL' => 1,
「致命的」 => -1,
'USE_PARAM_SEMICOLONS' => 0,
'PARAM_UTF8' => 0,
'DISABLE_UPLOADS' => 1,
'USE_CGI_PM_DEFAULTS' => 0,
「NPH」=> 0、
「POST_MAX」 => 102400、
'HEADERS_ONCE' => 0
}、
'anothervar' => [
「別の値」
]、
「ああ」 => [
「ララ」
]、
'thisvar' => [
「その値」
]、
'.fieldnames' => {
'anothervar' => 1,
「ああ」=> 1、
'thisvar' => 1
}、
'.header_printed' => 1
}, 'CGI::シンプル' );